当前位置:首页 » 编程语言 » 俄罗斯方块c语言编程

俄罗斯方块c语言编程

发布时间: 2023-08-17 17:43:30

❶ 用c语言编写俄罗斯方块程序 求详解

1、用C语言绘制图形界面

EasyX图形库(http://www.easyx.cn)即TC的图形库在VC下的移植。

包含库#include <graphics.h>

先初始化图形窗口

initgraph(WINDOW_WIDTH, WINDOW_HIGH) ;WINDOW_WIDTH为窗口的宽带,WINDOW_HIGH为窗口的高度。

清空绘图设备

cleardevice();

设置画笔颜色

setcolor(RED) ;

设置线条风格

setlinestyle(PS_SOLID, NULL, 0);

画矩形

rectangle

还有画线、显示文字等函数,可以参照其帮助文档。

注意:由于我们用的是EasyX图形库,故源文件后缀要为.cpp,但其中内容都是C的语法。

2、存储表示出俄罗斯方块的形状

一、我们可以用编号,不同的编号代表不同的俄罗斯方块,根据编号把不同方块的画法写在代码中,这样19种

方块就得有19种相应的代码来描绘。而且这样扩展性不好,若以后设计了新的方块,则需要更改大量源代码。

二、我们很自然的想到可用字模点阵的形式来表示,即设置一个4行4列的数组,元素置1即代表这个位置有小

方块,元素置0即代表这个位置无小方块,这个整个的4*4的数组组成俄罗斯方块的形状。

1000

1000

1100

0000

我们把俄罗斯方块点阵的数位存在rockArray中,我们可以事先把这19种方块的字模点阵自己转化成十六进制,然后在rockArray数组的初始化时赋值进去。

但这样做未免有点太费力,且扩展性也不太好,若以后设计的新方块种类加入,要改变数组rockArray中的值。

我们可以考虑把所有俄罗斯方块的点阵存储在配置文件中,在程序初始化时读取文件,把这些点阵转换成unsigned int的变量存储在rockArray中。

这样,以后我们增添新的方块形状只需要在配置文件中增加新的点阵即可。

@###

@###

@@##

####(为使得看起来更醒目,我们用@表示1,用#表示0)

3、让图形动起来

在某位置处用函数DrawRock在屏幕上画出俄罗斯方块,然后再擦除掉(即用背景色在原位置处重绘一次方块),最后在下落的下一个位置处用函数DrawRock在屏幕上画出俄罗斯方块,如此循环,中间用计时器间隔一段时间以控制下落的速度。

同理,按下屏幕的左右键也是如此,只是在按下键盘时把方块的位置重新计算了。

那么按下上方向键时,如何让方块翻转呢?

我们在配置文件中就把方块的顺时针翻转形态放在了一起:

@###

@###

@@##

####

@@@#

@###

####

####

@@##

#@##

#@##

####

##@#

@@@#

####

####

我们每按一次上方向键改变一次方块的形状即可。若一直按上键,形状应该是循环地翻滚。

我们想到了循环链表的数据结构可实现这个效果。

可是我们若把这些一种类的方块的各种形态串成循环链表形式,那么每次重新生成方块时我们就难以随机地生成方块了。

故还是得用数组来存储,但又要有循环链表的功能,于是我们想到了静态循环链表。

我们用结构体来作为一个方块在rockArray中的元素

typedef struct ROCK

{ //用来表示方块的形状(每一个字节是8位,用每4位表示方块中的一行)

unsigned int rockShapeBits ;

int nextRockIndex ; //下一个方块,在数组中的下标

} RockType ;

这样,当我们按下上方向键时,把传入函数DrawRock中的rockIndex变为当前方块结构体中的nextRockIndex即可。

❷ 一个简单的c语言写的俄罗斯方块程序

1、考虑怎么存储俄罗斯方块

俄罗斯方块的形状一共有19种类型,如果拿数组来表示的话,可能会比较会浪费空间(网上有很多实现代码)

考虑到每种方块形状的范围是4 *4的小方块,用 字模点阵的方式来存储,即设置一个4行4列的数组,元素置1即代表这个位置有小
方块,元素置0即代表这个位置无小方块,这个整个的4*4的数组组成俄罗斯方块的形状。
1000
1000
1100
0000
上述4*4来表示L形状的方块。
4*4 =16 bit 正好为short类型,所以每一个方块可以用一个short类型的数据来表示。

我们把俄罗斯方块点阵的数位存在rockArray中,我们可以事先把这19种方块的字模点阵自己转化成十六进制,然后在rockArray数组的初始化时赋值进去。
但是这种方式扩展性不好,每当有一种新方块时需要改动,
所以可以写一个配置文件来表示19种方块。(RockShape.ini)

@###@###@@######1234

从配置文件中读取方块的类型的代码在(Init.h的ReadRock函数中)在下面3中解释下代码如何实现

2如何画出方块

可以使用EasyX库来画出简单的图形,
EasyX库是在VC下实现TC的简单绘图功能的一个库,这个库很容易学会(直接 网络EasyX库,里面有详细的教程)

那么如何画出方块,方块已经存储到一个short类型中了
从short中读取出,可以用一个掩码mask = 1来与short的每个bit位相与,结果为1,则画出一个小方块;
函数声明:

void DisplayRock(int rockIdx, RockLocation_t* LocatePtr, bool displayed)1

参数1:表示在数组中的下标,取出short类型的方块表示数据
参数2:表示当前坐标,即画出方块的左上角的坐标x,y
参数3:true表示画出该方块,false 表示擦除该方块。

//方块在图形窗口中的位置(即定位4*4大块的左上角坐标) typedef struct LOCATE
{ int left; int top;
} RockLocation_t;123456

3如何实现同一种类型方块的翻转,

在按‘↑’时应该翻转同一种类型的方块,
比如下面的横杆和竖杆

@###@###@###@###@@@@############****1234567891011

可以假想成静态循环链表来实现这种方式
使同一种类型的方块循环起来,

用一个struct结构来表示一种方块

typedef struct ROCK
{ //用来表示方块的形状(每一个字节是8位,用每4位表示方块中的一行)
unsigned short rockShapeBits; int nextRockIndex; //下一个方块,在数组中的下标 } RockType;123456

定义一个RockType类型的数组来存储19种方块
RockType RockArray[19] = { (0, 0) };

当我们按“↑”时,把传入画方块函数DrawRock中的rockIndex变为当前方块结构体中的nextRockIndex即可。

简单解释下ReadRock函数的实现:当读取到空行的时候表示 一种方块已经读取完毕,当读取到****行时 表示同一种类型的方块读取完毕,具体看代码实现,代码中具体的注释

4、主要游戏实现的逻辑

贴一个预览图吧

注:上述预览图的游戏控制区和游戏显示区在Draw.h的DrawGameWindow()函数实现的

(1)在初始位置画出方块,在预览区画出下一次的方块
(2)方块有两种行为:响应键盘命令UserHitKeyBoard(),自由下落
如果敲击键盘了(w ,a ,s ,d, )空格表示暂停,如果在规定时间内没有敲击键盘的话,方块自由下落一个单位

if (kbhit()) //如果敲击键盘了 就处理按键
{
userHit = getch();
UserHitKeyBoard(userHit, &curRockIndex, &curRockLocation);
} //没有 就自动下移一个单位 :不能用else,因为可能按键不是上下左右
DWORD newtime = GetTickCount(); if (newtime - oldtime >= (unsigned int)(300) && moveAbled == TRUE)
{
oldtime = newtime;
DisplayRock(curRockIndex, &curRockLocation, false);
curRockLocation.top += ROCK_SQUARE_WIDTH; //下落一格
}1234567891011121314

(3)当方块落地(即不能下移了)时,判断是否满行,如果满行则消除,然后再判断游戏是否结束,游戏结束的话,直接退出游戏

判断满行:FullLine()函数,从最底下的一行开始判断,直到遇到一行空行,

while (count != xROCK_SQUARE_NUM ) //遇到空行 14
{
linefull = true; count = 0; for (int i = 1; i <= xROCK_SQUARE_NUM; ++i)
{ if (game_board[idx][i] == 0)
{
linefull = false; count++;
}
} if (linefull) //满行,消除当前行,更新分数
{
DelCurLine(idx);//消除满行
game_socres += 3;
UpdateSocres(game_socres);
idx++;//因为下面要减1
}
idx--;
}

(4)消除满行
将要删除的满行擦除:即将方块化成与背景色相同的,该代码为黑色
然后将上面的一行向下移,移一行删除一行,直到遇到空行
具体看代码的具体实现 game.h
void DelCurLine(int rowIdx)

(4)判断方块是否能移动
在game.h中实现

bool MoveAble(int rockIndex, RockLocation_t* currentLocatePtr, int f_direction)1

**比较当前位置的坐标(左上角)开始,能否放下rockIndex的方块。
注:f_direction为”↑”的话,则传入的rockIndex为下一个方块**

如果不能移动的话,给游戏game_board设置标记表示该位置被占有

//全局变量-游戏板的状态描述(即表示当前界面哪些位置有方块) //0表示没有,1表示有(多加了两行和两列,形成一个围墙,便于判断方块是否能够移动) int game_board[yROCK_SQUARE_NUM + 2][xROCK_SQUARE_NUM + 2] = { 0 };123

实现过程遇到的一些问题

(1)在快速下落的时候,可能方块会掉出围墙的范围内,
快速下落是使方块每次下落2个单位距离。
在判断不能下落时,使当前坐标的top即y减去一个单位的距离

(2)遇到多行满行时消除不了,
在判断满行时,循环找出满行,找出一个满行,就消除一行,然后继续判断是否满行,直到遇到空行

❸ #高手往这看#用c语言编写俄罗斯方块代码,要能在codeblocks上运行的。

main.c里面
#include <stdio.h>
#include <stdlib.h>
#include "fangkuai.h"
#include <time.h>
int main()
{
Manager manager;
Control control;
initGame(&manager,&control);
do {
printPrompting();
printPoolBorder();
runGame(&manager,&control);
if(ifPlayAgain()){
SetConsoleTextAttribute(Output,0x7);
system("cls");
startGame(&manager,&control);
}
else{
break;
}
}
while(1);
gotoxyFull(0,0);
CloseHandle(Output);
return 0;
}
.h里面
#ifndef FANGKUAI_H_INCLUDED
#define FANGKUAI_H_INCLUDED

#include <stdio.h> //标准输入输出
#include <string.h> //字符数组
#include <stdlib.h> //标准库
#include <time.h> //日期和时间
#include <conio.h> //控制台输入输出
#include <windows.h> // windows控制台
#include <stdbool.h> //标准布尔函数
//定义句柄,结构体,数组;函数声明
//定义方块数组,[7][4],7种方块,每种4个状态
static const unsigned int TetrisTable[7][4]={
{0x4444,0x0f00,0x2222,0x00f0},
{0x04e0,0x4640,0x0720,0x0262},
{0x0446,0x0e80,0x6220,0x0170},
{0x0622,0x02e0,0x4460,0x0740},
{0x0630,0x0264,0x0c60,0x2640},
{0x0462,0x06c0,0x4620,0x0360},
{0x0660,0x0660,0x0660,0x0660},
};
typedef struct TetrisManger{
unsigned int pool[28];
int x;int y;
int type[3];
int orientation[3];
unsigned score;
unsigned erasedCount[4];
unsigned erasedTotal;
unsigned tetrisCount[7];
unsigned tetrisTotal;
bool dead;
}Manager;
static const unsigned int initTetrisPool[28]={
0xc003,0xc003,0xc003,0xc003,0xc003,0xc003,0xc003,
0xc003,0xc003,0xc003,0xc003,0xc003,0xc003,0xc003,
0xc003,0xc003,0xc003,0xc003,0xc003,0xc003,0xc003,
0xc003,0xc003,0xc003,0xc003,0xc003,0xffff,0xffff
};
typedef struct TetresControl{
bool pause;
bool clockwise;
int direction;
int color[28][16];
}Control;
HANDLE Output;
void initGame(Manager *manager,Control *control);
void gotoxyFull(short x,short y);
void printPrompting();
void printPoolBorder();
void printScore(const Manager *manager);
void printNextTetres(const Manager *manager);
void startGame(Manager *manager,Control *control);
void initTetris(Manager *manager);
void insertTetris(Manager *manager);
void setPoolColor(const Manager *manager,Control *control);
void printCurrentTetris(const Manager *manager,const Control *control);
void printTetrisPool(const Manager *manager,const Control *control);
bool checkCollision(const Manager *manager);
void removeTetris(Manager *manager);
void moveDownTetris(Manager *manager,Control *control);
void runGame(Manager *manager,Control *control);
void horzMoveTetris(Manager *manager,Control *control);
void keydownControl(Manager *manager,Control *control,int key);
void rotateTetris(Manager *manager,Control *control);
void dropTetris(Manager *manager,Control *control);
bool checkErasing(Manager *manager,Control *control);
bool ifPlayAgain();

#endif // FANGKUAI_H_INCLUDED

.c里面
#include "fangkuai.h"
#include <stdio.h>
#include <windows.h>
void initGame(Manager *manager,Control *control)//初始化游戏
{
SetConsoleTitle("俄罗斯方块"); //设置窗口标题
Output=GetStdHandle(STD_OUTPUT_HANDLE); //获取标准输出句柄
CONSOLE_CURSOR_INFO INFO; //定义光标属性结构体变量
INFO.dwSize=1; //设置光标高度值
INFO.bVisible=FALSE; //设置光标隐藏值
SetConsoleCursorInfo(Output,&INFO); //设置光标属性
startGame(manager,control);
}
//全角定位光标
void gotoxyFull(short x,short y) //全角方式定位
{
static COORD cd; //定义结构体变量
cd.X=2*x; //结构体变量 X=2x
cd.Y=y;
SetConsoleCursorPosition(Output,cd);//设置光标位置
}
//显示右下角按键提示信息
void printPrompting(){
SetConsoleTextAttribute(Output,0x0b);//设置显示颜色为蓝色光亮
gotoxyFull(26,10);
printf("■控制:");
gotoxyFull(27,12);
printf("□向左移动:← A 4");
gotoxyFull(27,13);
printf("□向右移动:→ D 6");
gotoxyFull(27,14);
printf("□向下移动:↓ S 2");
gotoxyFull(27,15);
printf("□顺时针转:↑ W 8");
gotoxyFull(27,16);
printf("□逆时针转:0");
gotoxyFull(27,17);
printf("□直接落地:空格");
gotoxyFull(27,18);
printf("□暂停游戏:回车");
gotoxyFull(26,23);
printf("■BY YU");
}
//显示游戏池白色边框
void printPoolBorder(){
SetConsoleTextAttribute(Output,0xF0);//设置背景色为白色高亮
int y=1;
for (y=1;y<23;y++){
gotoxyFull(10,y); //(10,1) 定位到(10,22)
printf("%2s","");
gotoxyFull(23,y); //(23,1)定位到(23,22)
printf("%2s","");
}
gotoxyFull(10,23);//底部一行
printf("%28s",""); //14个字符,每个两位,左边、右边白色,中间12
}
//显示得分、消行数、方块数
void printScore(const Manager *manager){
SetConsoleTextAttribute(Output,0x0E);//设置颜色为黄色高亮
gotoxyFull(2,2);
printf("■得分:%u",manager->score);
gotoxyFull(1,6);
printf("■消行总数:%u",manager->erasedTotal);
int i;
for (i=0;i<4;i++){
gotoxyFull(2,7+i);
printf("□消%d:%u",i+1,manager->erasedCount[i]);
}
gotoxyFull(1,15);
printf("■方块总数:%u",manager->tetrisTotal);
static const char *tetrisName="ITLJZSO";
for (i=0;i<7;i++){
gotoxyFull(2,17+i);
printf("□%c形:%u",tetrisName[i],manager->tetrisCount[i]);
}
}
void printNextTetres(const Manager *manager)//显示下一个,下下一个方块
{
SetConsoleTextAttribute(Output,0x0f);//设置前景色为白色高亮
gotoxyFull(26,1);
printf("┌─────────┬─────────┐");
gotoxyFull(26,2);
printf("│%9s│%9s│","","");
gotoxyFull(26,3);
printf("│%9s│%9s│","","");
gotoxyFull(26,4);
printf("│%9s│%9s│","","");
gotoxyFull(26,5);
printf("│%9s│%9s│","","");
gotoxyFull(26,6);
printf("└─────────┴─────────┘");
//显示下一个方块
unsigned int tetris ;
int i;
tetris=TetrisTable[manager->type[1]][manager->orientation[1]];
SetConsoleTextAttribute(Output,manager->type[1]|8);
for (i=0;i<16;i++){
gotoxyFull(27+(i&3),2+(i>>2));
((tetris<<i)&0x8000) ? printf("■"):printf("%2s","");
}
tetris=TetrisTable[manager->type[2]][manager->type[2]];
SetConsoleTextAttribute(Output,0x08);
for(i=0;i<16;i++){
gotoxyFull(32+(i&3),2+(i>>2));
((tetris<<i)&0x8000)?printf("■"):printf("%2s","");
}
}
void startGame(Manager *manager,Control *control)//开始游戏
{
memset(manager,0,sizeof(Manager));
memcpy(manager->pool,initTetrisPool,sizeof(unsigned int [28]));//复制游戏池数据
srand((unsigned)time(NULL));//设置随机数种子
manager->type[1]=rand()%7;//下一个方块类型
manager->orientation[1]=rand()%4;//下一个方块状态
manager->type[2]=rand()%7;//下下一个方块类型
manager->orientation[2]=rand()%4;//下下一个方块状态
memset(control,0,sizeof(Control));//初始化控制结构体为0
initTetris(manager); //初始化方块
setPoolColor(manager,control);//初始化方块,若没有碰撞,插入方块,需要设置颜色
}
void initTetris(Manager *manager)//出第一个方块
{
unsigned int tetris;
manager->type[0]=manager->type[1];
manager->orientation[0]=manager->orientation[1];
manager->type[1]=manager->type[2];
manager->orientation[1]=manager->orientation[2];
manager->type[2]=rand()%7;
manager->orientation[2]=rand()%4;
tetris=TetrisTable[manager->type[0]][manager->orientation[0]];
manager->x=6;
manager->y=4;
if(checkCollision(manager)){
manager->dead=true;
}
else{
insertTetris(manager);
}
++manager->tetrisTotal;
++manager->tetrisCount[manager->type[0]];
printNextTetres(manager);
printScore(manager);
}
//插入方块到游戏池
void insertTetris(Manager *manager){
unsigned int tetris=TetrisTable[manager->type[0]][manager->orientation[0]];//相对于y的位置
manager->pool[manager->y+0]|=(((tetris<<0x0)&0xF000)>>manager->x);//或等于
manager->pool[manager->y+1]|=(((tetris<<0x4)&0xF000)>>manager->x);
manager->pool[manager->y+2]|=(((tetris<<0x8)&0xF000)>>manager->x);
manager->pool[manager->y+3]|=(((tetris<<0xc)&0xF000)>>manager->x);
}
//设置游戏颜色
void setPoolColor(const Manager *manager, Control *control){
int i,x,y;
/* i 当前方块值 0----15
x 设置颜色的列 x=manager->x+&3
y 设置颜色的行 y=manager->y+i>>2 */
unsigned int tetris;
tetris=TetrisTable[manager->type[0]][manager->orientation[0]];
for(i=0;i<16;i++){
y=manager->y+(i>>2);
if(y>25){
break;
}
x=manager->x+(i&3);
if((tetris<<i)&0x8000){
control->color[y][x]=(manager->type[0]|8);
}
}
}
//显示当前方块
void printCurrentTetris(const Manager *manager,const Control *control){
int x,y;
y=(manager->y>4)?(manager->y-1):4;
for (;y<26&&y<manager->y+4;y++){
x=(manager->x>2)?(manager->x-1):2;
for (;x<14&x<manager->x+5;x++) {
gotoxyFull(x+9,y-3);
if((manager->pool[y]<<x) & 0x8000){
SetConsoleTextAttribute(Output,control->color[y][x]);
printf("■");
}
else{
SetConsoleTextAttribute(Output,0);
printf("%2s","");
}
}
}
}
//显示游戏池
void printTetrisPool(const Manager *manager,const Control *control){
int x,y;
for(y=4;y<26;y++)
{
gotoxyFull(11,y-3);
for(x=2;x<14;x++)
{
if((manager->pool[y]<<x) & 0x8000)
{
SetConsoleTextAttribute(Output,control->color[y][x]);
printf("■");
}
else {
SetConsoleTextAttribute(Output,0);
printf("%2s","");
}
}
}
}
//碰撞检测
bool checkCollision(const Manager *manager){
unsigned int tetris;
tetris=TetrisTable[manager->type[0]][manager->orientation[0]];//准备插入的当前方块
unsigned int dest;//游戏池中4行4列的值
dest=0;
dest|=(((manager->pool[manager->y+0]<<manager->x)&0xF000)>>0x0);
dest|=(((manager->pool[manager->y+1]<<manager->x)&0xF000)>>0x4);//左移x,右移4
dest|=(((manager->pool[manager->y+2]<<manager->x)&0xF000)>>0x8);
dest|=(((manager->pool[manager->y+3]<<manager->x)&0xF000)>>0xc);
return((dest&tetris)!=0);
}
//移除方块
void removeTetris(Manager *manager){
unsigned int tetris;
tetris=TetrisTable[manager->type[0]][manager->orientation[0]];//准备插入的当前方块,当前方块值
manager->pool[manager->y+0]&=~(((tetris<<0x0)&0xF000)>>manager->x);//左移0保留 最高,其余清零,右移x,游戏中方块列位置,取反,原来&后面,存
manager->pool[manager->y+1]&=~(((tetris<<0x4)&0xF000)>>manager->x);
manager->pool[manager->y+2]&=~(((tetris<<0x8)&0xF000)>>manager->x);
manager->pool[manager->y+3]&=~(((tetris<<0xc)&0xF000)>>manager->x);
}
//向下移动方块
void moveDownTetris(Manager *manager,Control *control){
int y=manager->y;
removeTetris(manager);
++manager->y;
if(checkCollision(manager)){
manager->y=y;
insertTetris(manager);
if(checkErasing(manager,control))
{
printTetrisPool(manager,control);
}
}
else{
insertTetris(manager);
setPoolColor(manager,control);
printCurrentTetris(manager,control);
}
}
//运行游戏
void runGame(Manager *manager,Control *control){
clock_t clockNow,clockLast;
clockLast=clock();
printTetrisPool(manager,control);
while (!manager->dead){
while(_kbhit()){
keydownControl(manager,control,getch());
}
if (!control->pause){
clockNow=clock();
if(clockNow-clockLast>0.45F*CLOCKS_PER_SEC){
clockLast=clockNow;
moveDownTetris(manager,control);
}
}
}
}

❹ 求一个简单的c语言写的俄罗斯方块程序

刚学c的时候编的,所以程序规范性以及代码的执行效率都不高,而且程序超长。但应该没有太难的语句。
#include<stdio.h>
#include<string.h>
#include<bios.h>
#include<stdlib.h>
#include<time.h>
#include<dos.h>
int dx[4],dy[4]; /*定义全局变量*/
int zt1,zt2,str[15][19];
/*str[15][19]是把整个屏幕分为15*19个方格,每一个方格用一个数组单元表示,
如果=15,则这个方格已被占用,=0,则还是空的*/
int cx[8][5][4],cy[8][5][4]; /*该变量表示每种状态下,旋转时坐标的改变*/
int x,y,j,ji,c;
int maxzt[8]=; /*各个种类的方块分别有几种状态*/
cir() /*旋转的处理函数*/
{ dx[0]=dx[0]+cx[zt1][zt2][0];dy[0]=dy[0]+cy[zt1][zt2][0];
dx[2]=dx[2]+cx[zt1][zt2][2];dy[2]=dy[2]+cy[zt1][zt2][2];
dx[3]=dx[3]+cx[zt1][zt2][3];dy[3]=dy[3]+cy[zt1][zt2][3];
}
jiance() /*检测旋转或移动能否进行的函数,能则j=1,不能j=0*/
{ j=1;
for(ji=0;ji<4;ji++)
{ x=dx[ji];y=dy[ji];
if(str[x][y]!=' ') j=0;
}
c=bioskey(1);
if(c!=0) c=bioskey(0);
}
main()
{ int dotx[4],doty[4],score; /*dotx[]doty[]表示一个方块个点的坐标*/
int ddx,ddy;
int rzt1,rzt2,i,u,t=1;
int a[5],b[11],o,p,an,bn;
int rotx[4],roty[4],spd=0;
begin: system("cls"); /*游戏初始化阶段*/
printf("londing...");
for(i=0;i<12;i++) /*变量初始阶段*/
{ for(u=0;u<19;u++)
str[i][u]=' ';
}
for(i=0;i<12;i++)

for(u=0;u<19;u++)

cx[1][1][0]=1;cx[1][1][2]=-1;cx[1][1][3]=-2; /*对旋转变量进行赋值*/
cy[1][1][0]=1;cy[1][1][2]=-1;cy[1][1][3]=-2;
cx[1][2][0]=-1;cx[1][2][2]=1;cx[1][2][3]=2;
cy[1][2][0]=-1;cy[1][2][2]=1;cy[1][2][3]=2;

cx[2][1][0]=0;cx[2][1][2]=0;cx[2][1][3]=0;
cy[2][1][0]=0;cy[2][1][2]=0;cy[2][1][3]=0;

cx[3][1][0]=1;cx[3][1][2]=-1;cx[3][1][3]=1;
cy[3][1][0]=-1;cy[3][1][2]=1;cy[3][1][3]=1;
cx[3][2][0]=1;cx[3][2][2]=-1;cx[3][2][3]=-1;
cy[3][2][0]=1;cy[3][2][2]=-1;cy[3][2][3]=1;
cx[3][3][0]=-1;cx[3][3][2]=1;cx[3][3][3]=-1;
cy[3][3][0]=1;cy[3][3][2]=-1;cy[3][3][3]=-1;
cx[3][4][0]=-1;cx[3][4][2]=1;cx[3][4][3]=1;
cy[3][4][0]=-1;cy[3][4][2]=1;cy[3][4][3]=-1;

cx[4][1][0]=-1;cx[4][1][2]=1;cx[4][1][3]=2;
cy[4][1][0]=1;cy[4][1][2]=1;cy[4][1][3]=0;
cx[4][2][0]=1;cx[4][2][2]=-1;cx[4][2][3]=-2;
cy[4][2][0]=-1;cy[4][2][2]=-1;cy[4][2][3]=0;

cx[5][1][0]=1;cx[5][1][2]=1;cx[5][1][3]=0;
cy[5][1][0]=-1;cy[5][1][2]=1;cy[5][1][3]=2;
cx[5][2][0]=-1;cx[5][2][2]=-1;cx[5][2][3]=0;
cy[5][2][0]=1;cy[5][2][2]=-1;cy[5][2][3]=-2;

cx[6][1][0]=1;cx[6][1][2]=-1;cx[6][1][3]=0;
cy[6][1][0]=-1;cy[6][1][2]=1;cy[6][1][3]=2;
cx[6][2][0]=1;cx[6][2][2]=-1;cx[6][2][3]=-2;
cy[6][2][0]=1;cy[6][2][2]=-1;cy[6][2][3]=0;
cx[6][3][0]=-1;cx[6][3][2]=1;cx[6][3][3]=0;
cy[6][3][0]=1;cy[6][3][2]=-1;cy[6][3][3]=-2;
cx[6][4][0]=-1;cx[6][4][2]=1;cx[6][4][3]=2;
cy[6][4][0]=-1;cy[6][4][2]=1;cy[6][4][3]=0;

cx[7][1][0]=-1;cx[7][1][2]=1;cx[7][1][3]=2;
cy[7][1][0]=1;cy[7][1][2]=-1;cy[7][1][3]=0;
cx[7][2][0]=-1;cx[7][2][2]=1;cx[7][2][3]=0;
cy[7][2][0]=-1;cy[7][2][2]=1;cy[7][2][3]=2;
cx[7][3][0]=1;cx[7][3][2]=-1;cx[7][3][3]=-2;
cy[7][3][0]=-1;cy[7][3][2]=1;cy[7][3][3]=0;
cx[7][4][0]=1;cx[7][4][2]=-1;cx[7][4][3]=0;
cy[7][4][0]=1;cy[7][4][2]=-1;cy[7][4][3]=-2;

srand(time(0)); /*对随机数函数rand()进行初始化*/
zt1=rand()%7+1; /*生成第一、二个方块*/
if(zt1==2) zt2=1;
if(zt1==1||zt1==4||zt1==5) zt2=rand()%2+1;
if(zt1==3||zt1==6||zt1==7) zt2=rand()%4+1;
rzt1=rand()%7+1;
if(rzt1==2) rzt2=1;
if(rzt1==1||rzt1==4||rzt1==5) rzt2=rand()%2+1;
if(rzt1==3||rzt1==6||rzt1==7) rzt2=rand()%4+1;
score=0;
for(o=1;o<11;o++) b[o]=0;
switch(zt1*10+zt2)
/*zt1和zt2分别代表方块的种类和状态,这步是根据这两个变量确定方块的四个点的坐标*/
{ case 11: dotx[0]=4;dotx[1]=5;dotx[2]=6;dotx[3]=7;
doty[0]=2;doty[1]=2;doty[2]=2;doty[3]=2;
break;
case 12: dotx[0]=5;dotx[1]=5;dotx[2]=5;dotx[3]=5;
doty[0]=4;doty[1]=3;doty[2]=2;doty[3]=1;
break;
case 21: dotx[0]=5;dotx[1]=6;dotx[2]=5;dotx[3]=6;
doty[0]=1;doty[1]=1;doty[2]=2;doty[3]=2;
break;
case 31: dotx[0]=4;dotx[1]=5;dotx[2]=6;dotx[3]=5;
doty[0]=2;doty[1]=2;doty[2]=2;doty[3]=1;
break;
case 32: dotx[0]=5;dotx[1]=5;dotx[2]=5;dotx[3]=6;
doty[0]=1;doty[1]=2;doty[2]=3;doty[3]=2;
break;
case 33: dotx[0]=6;dotx[1]=5;dotx[2]=4;dotx[3]=5;
doty[0]=1;doty[1]=1;doty[2]=1;doty[3]=2;
break;
case 34: dotx[0]=6;dotx[1]=6;dotx[2]=6;dotx[3]=5;
doty[0]=3;doty[1]=2;doty[2]=1;doty[3]=2;
break;
case 41: dotx[0]=6;dotx[1]=5;dotx[2]=5;dotx[3]=4;
doty[0]=2;doty[1]=2;doty[2]=1;doty[3]=1;
break;
case 42: dotx[0]=5;dotx[1]=5;dotx[2]=6;dotx[3]=6;
doty[0]=3;doty[1]=2;doty[2]=2;doty[3]=1;
break;
case 51: dotx[0]=4;dotx[1]=5;dotx[2]=5;dotx[3]=6;
doty[0]=2;doty[1]=2;doty[2]=1;doty[3]=1;
break;
case 52: dotx[0]=5;dotx[1]=5;dotx[2]=6;dotx[3]=6;
doty[0]=1;doty[1]=2;doty[2]=2;doty[3]=3;
break;
case 61: dotx[0]=4;dotx[1]=5;dotx[2]=6;dotx[3]=6;
doty[0]=2;doty[1]=2;doty[2]=2;doty[3]=1;
break;
case 62: dotx[0]=5;dotx[1]=5;dotx[2]=5;dotx[3]=6;
doty[0]=1;doty[1]=2;doty[2]=3;doty[3]=3;
break;
case 63: dotx[0]=6;dotx[1]=5;dotx[2]=4;dotx[3]=4;
doty[0]=1;doty[1]=1;doty[2]=1;doty[3]=2;
break;
case 64: dotx[0]=6;dotx[1]=6;dotx[2]=6;dotx[3]=5;
doty[0]=3;doty[1]=2;doty[2]=1;doty[3]=1;
break;
case 71: dotx[0]=6;dotx[1]=5;dotx[2]=4;dotx[3]=4;
doty[0]=2;doty[1]=2;doty[2]=2;doty[3]=1;
break;
case 72: dotx[0]=5;dotx[1]=5;dotx[2]=5;dotx[3]=6;
doty[0]=3;doty[1]=2;doty[2]=1;doty[3]=1;
break;
case 73: dotx[0]=4;dotx[1]=5;dotx[2]=6;dotx[3]=6;
doty[0]=1;doty[1]=1;doty[2]=1;doty[3]=2;
break;
case 74: dotx[0]=6;dotx[1]=6;dotx[2]=6;dotx[3]=5;
doty[0]=1;doty[1]=2;doty[2]=3;doty[3]=3;
break;
}
switch(rzt1*10+rzt2) /*确定第二个方块各个点的坐标*/
{ case 11: rotx[0]=4;rotx[1]=5;rotx[2]=6;rotx[3]=7;
roty[0]=2;roty[1]=2;roty[2]=2;roty[3]=2;
break;
case 12: rotx[0]=5;rotx[1]=5;rotx[2]=5;rotx[3]=5;
roty[0]=4;roty[1]=3;roty[2]=2;roty[3]=1;
break;
case 21: rotx[0]=5;rotx[1]=6;rotx[2]=5;rotx[3]=6;
roty[0]=1;roty[1]=1;roty[2]=2;roty[3]=2;
break;
case 31: rotx[0]=4;rotx[1]=5;rotx[2]=6;rotx[3]=5;
roty[0]=2;roty[1]=2;roty[2]=2;roty[3]=1;
break;
case 32: rotx[0]=5;rotx[1]=5;rotx[2]=5;rotx[3]=6;
roty[0]=1;roty[1]=2;roty[2]=3;roty[3]=2;
break;
case 33: rotx[0]=6;rotx[1]=5;rotx[2]=4;rotx[3]=5;
roty[0]=1;roty[1]=1;roty[2]=1;roty[3]=2;
break;
case 34: rotx[0]=6;rotx[1]=6;rotx[2]=6;rotx[3]=5;
roty[0]=3;roty[1]=2;roty[2]=1;roty[3]=2;
break;
case 41: rotx[0]=6;rotx[1]=5;rotx[2]=5;rotx[3]=4;
roty[0]=2;roty[1]=2;roty[2]=1;roty[3]=1;
break;
case 42: rotx[0]=5;rotx[1]=5;rotx[2]=6;rotx[3]=6;
roty[0]=3;roty[1]=2;roty[2]=2;roty[3]=1;
break;
case 51: rotx[0]=4;rotx[1]=5;rotx[2]=5;rotx[3]=6;
roty[0]=2;roty[1]=2;roty[2]=1;roty[3]=1;
break;
case 52: rotx[0]=5;rotx[1]=5;rotx[2]=6;rotx[3]=6;
roty[0]=1;roty[1]=2;roty[2]=2;roty[3]=3;
break;
case 61: rotx[0]=4;rotx[1]=5;rotx[2]=6;rotx[3]=6;
roty[0]=2;roty[1]=2;roty[2]=2;roty[3]=1;
break;
case 62: rotx[0]=5;rotx[1]=5;rotx[2]=5;rotx[3]=6;
roty[0]=1;roty[1]=2;roty[2]=3;roty[3]=3;
break;
case 63: rotx[0]=6;rotx[1]=5;rotx[2]=4;rotx[3]=4;
roty[0]=1;roty[1]=1;roty[2]=1;roty[3]=2;
break;
case 64: rotx[0]=6;rotx[1]=6;rotx[2]=6;rotx[3]=5;
roty[0]=3;roty[1]=2;roty[2]=1;roty[3]=1;
break;
case 71: rotx[0]=6;rotx[1]=5;rotx[2]=4;rotx[3]=4;
roty[0]=2;roty[1]=2;roty[2]=2;roty[3]=1;
break;
case 72: rotx[0]=5;rotx[1]=5;rotx[2]=5;rotx[3]=6;
roty[0]=3;roty[1]=2;roty[2]=1;roty[3]=1;
break;
case 73: rotx[0]=4;rotx[1]=5;rotx[2]=6;rotx[3]=6;
roty[0]=1;roty[1]=1;roty[2]=1;roty[3]=2;
break;
case 74: rotx[0]=6;rotx[1]=6;rotx[2]=6;rotx[3]=5;
roty[0]=1;roty[1]=2;roty[2]=3;roty[3]=3;
break;
}
system("cls"); /*显示初始阶段*/
printf("\n\n\n"); /*游戏区域下移3*/
for(u=0;u<19;u++)
{ for(i=0;i<12;i++)
printf("%c",str[i][u]);
printf("\n");
}
gotoxy(16,5);printf("--------");
gotoxy(16,12);printf("--------");
for(i=6;i<12;i++)

for(i=6;i<12;i++)

for(i=0;i<4;i++)
{ gotoxy(rotx[i]+14,roty[i]+6);printf("%c",15);
}
begin2: delay(26000); /*游戏开始,延迟1*/
speed: delay(10000); /*加速,延迟2*/
gotoxy(16,14);printf("Score:%d",score);
for(i=0;i<4;i++)
{ gotoxy(dotx[i]+1,doty[i]+4);printf(" ");
ddx=dotx[i];ddy=doty[i];
str[ddx][ddy]=' ';
}
an=an-0.4; /*表示按键是否一直按着,用于方块落地后的移动*/
c=bioskey(1); /*按键处理部分*/
/*bioskey(1)是用来检测是否按下案件的函数*/
if(c!=0)
{ c=bioskey(0);
if(c==8292||c==19712)
{ for(i=0;i<4;i++)

jiance();
for(i=0;i<4;i++)
dotx[i]=(j)? dx[i] : dotx[i];
an=(j||bn);
}
if(c==7777||c==19200)
{ for(i=0;i<4;i++)

jiance();
for(i=0;i<4;i++)
dotx[i]=(j)? dx[i] : dotx[i];
an=(j||bn);
}
if(c==6512) /*暂停的处理*/
{ while(1)
{ c=bioskey(0);
if(c==6512) break;
}
goto begin3;
}
if(c==8051||c==20480) spd=1; /*加速(spd==1表示加速状态)*/
if(c==4471||c==18432) /*旋转的处理*/
{ for(i=0;i<4;i++)

/*dx[]与dy[]是临时变量,这样一旦判断为不能旋转,就可方便的回复旋转前的坐标*/
cir(); /*旋转*/
jiance(); /*判断旋转是否能进行*/
for(i=0;i<4;i++)

/*根据jiance()得到的j值,判断是对dotx[]与doty[]赋旋转后的还是旋转前的值*/
if(j==1) /*如果旋转可已经行,就对原方块的状态进行改变*/
{ an=(j||bn);zt2=zt2+1;
if(zt2>maxzt[zt1]) zt2=1;
goto overif; /*结束旋转的处理*/
}
for(i=0;i<4;i++)

/*如果不能旋转,再判断坐标右移一个后能否旋转*/
cir();
jiance();
for(i=0;i<4;i++)

if(j==1)
{ an=(j||bn);zt2=zt2+1;
if(zt2>maxzt[zt1]) zt2=1;
goto overif;
}
if(dotx[2]==1) goto overif;
for(i=0;i<4;i++)

/*判断坐标左移一个后能否旋转*/
cir();
jiance();
for(i=0;i<4;i++)

if(j==1)
{ an=(j||bn);zt2=zt2+1;
if(zt2>maxzt[zt1]) zt2=1;
goto overif;
}
overif: ;
}
}
begin3: for(i=0;i<4;i++) /*方块下移的处理*/

jiance();
bn=j;
for(i=0;i<4;i++)
doty[i]=(j)? dy[i] : doty[i];
for(i=0;i<4;i++)
{ gotoxy(dotx[i]+1,doty[i]+4);printf("%c",15);
ddx=dotx[i];ddy=doty[i];
str[ddx][ddy]=15;
}
if(j==1&&spd==1)
if(j==1||an>0) goto begin2;
for(u=17;u>0;u--) /*方块停止下移(方块移动到底了)的处理*/
{ for(i=1;i<11;i++) /*判断每一行是否排满*/
if(str[i][u]==15) b[i]=1;
if (b[1]+b[2]+b[3]+b[4]+b[5]+b[6]+b[7]+b[8]+b[9]+b[10]<10)
{ for(o=1;o<11;o++) b[o]=0;
continue;
}
for(o=1;o<11;o++) b[o]=0;
a[t]=u;t++;
}
score+=(t)*(t-1)/2;
for(i=1;i<11;i++)
if(str[i][1]==15) b[i]=1;
if (b[1]+b[2]+b[3]+b[4]+b[5]+b[6]+b[7]+b[8]+b[9]+b[10]>0 &&t==1) goto over;
for(o=1;o<11;o++) b[o]=0;
if(t==1) goto ran;
switch(t) /*消除方块的处理,t=要消除的函数+1*/

/*将要消除的行中,最上面一行,上面的方格整体下移,下面的case 4,3,2类似*/
case 4: for(u=a[3];u>1;u--)
case 3: for(u=a[2];u>1;u--)
case 2: for(u=a[1];u>1;u--)
}
t=1;
for(u=1;u<18;u++)
{ for(i=1;i<11;i++)
{ gotoxy(i+1,u+4);
printf("%c",str[i][u]);
}
}
ran: zt1=rzt1;zt2=rzt2;rzt1=rand()%7+1; /*生成下两个方块*/
if(rzt1==2) rzt2=1;
if(rzt1==1||rzt1==4||rzt1==5) rzt2=rand()%2+1;
if(rzt1==3||rzt1==6||rzt1==7) rzt2=rand()%4+1;
for(i=0;i<4;i++)
{ dotx[i]=rotx[i];doty[i]=roty[i];
gotoxy(dotx[i]+1,doty[i]+4);printf("%c",15);
}
switch(rzt1*10+rzt2)
{ case 11: rotx[0]=4;rotx[1]=5;rotx[2]=6;rotx[3]=7;
roty[0]=2;roty[1]=2;roty[2]=2;roty[3]=2;
break;
case 12: rotx[0]=5;rotx[1]=5;rotx[2]=5;rotx[3]=5;
roty[0]=4;roty[1]=3;roty[2]=2;roty[3]=1;
break;
case 21: rotx[0]=5;rotx[1]=6;rotx[2]=5;rotx[3]=6;
roty[0]=1;roty[1]=1;roty[2]=2;roty[3]=2;
break;
case 31: rotx[0]=4;rotx[1]=5;rotx[2]=6;rotx[3]=5;
roty[0]=2;roty[1]=2;roty[2]=2;roty[3]=1;
break;
case 32: rotx[0]=5;rotx[1]=5;rotx[2]=5;rotx[3]=6;
roty[0]=1;roty[1]=2;roty[2]=3;roty[3]=2;
break;
case 33: rotx[0]=6;rotx[1]=5;rotx[2]=4;rotx[3]=5;
roty[0]=1;roty[1]=1;roty[2]=1;roty[3]=2;
break;
case 34: rotx[0]=6;rotx[1]=6;rotx[2]=6;rotx[3]=5;
roty[0]=3;roty[1]=2;roty[2]=1;roty[3]=2;
break;
case 41: rotx[0]=6;rotx[1]=5;rotx[2]=5;rotx[3]=4;
roty[0]=2;roty[1]=2;roty[2]=1;roty[3]=1;
break;
case 42: rotx[0]=5;rotx[1]=5;rotx[2]=6;rotx[3]=6;
roty[0]=3;roty[1]=2;roty[2]=2;roty[3]=1;
break;
case 51: rotx[0]=4;rotx[1]=5;rotx[2]=5;rotx[3]=6;
roty[0]=2;roty[1]=2;roty[2]=1;roty[3]=1;
break;
case 52: rotx[0]=5;rotx[1]=5;rotx[2]=6;rotx[3]=6;
roty[0]=1;roty[1]=2;roty[2]=2;roty[3]=3;
break;
case 61: rotx[0]=4;rotx[1]=5;rotx[2]=6;rotx[3]=6;
roty[0]=2;roty[1]=2;roty[2]=2;roty[3]=1;
break;
case 62: rotx[0]=5;rotx[1]=5;rotx[2]=5;rotx[3]=6;
roty[0]=1;roty[1]=2;roty[2]=3;roty[3]=3;
break;
case 63: rotx[0]=6;rotx[1]=5;rotx[2]=4;rotx[3]=4;
roty[0]=1;roty[1]=1;roty[2]=1;roty[3]=2;
break;
case 64: rotx[0]=6;rotx[1]=6;rotx[2]=6;rotx[3]=5;
roty[0]=3;roty[1]=2;roty[2]=1;roty[3]=1;
break;
case 71: rotx[0]=6;rotx[1]=5;rotx[2]=4;rotx[3]=4;
roty[0]=2;roty[1]=2;roty[2]=2;roty[3]=1;
break;
case 72: rotx[0]=5;rotx[1]=5;rotx[2]=5;rotx[3]=6;
roty[0]=3;roty[1]=2;roty[2]=1;roty[3]=1;
break;
case 73: rotx[0]=4;rotx[1]=5;rotx[2]=6;rotx[3]=6;
roty[0]=1;roty[1]=1;roty[2]=1;roty[3]=2;
break;
case 74: rotx[0]=6;rotx[1]=6;rotx[2]=6;rotx[3]=5;
roty[0]=1;roty[1]=2;roty[2]=3;roty[3]=3;
break;
}
for(i=6;i<12;i++) /*刷新一下用来显示下一个方块的那个区域*/

for(i=6;i<12;i++)
for(u=17;u<23;u++)
for(i=0;i<4;i++)

c=bioskey(1);an=0;
if(c!=0) c=bioskey(0);
if(spd==1)
goto begin2;
over: system("cls");
gotoxy(36,11);printf("GAME OVER");
bioskey(0);
system("cls");
printf("Your score is %d\n\n",score);
printf("Press 'Q' to exit\nIf you want to play again,please press other keys.");
score=0;
c=bioskey(0);
if(c!=4209) goto begin;
}
另外,团IDC网上有许多产品团购,便宜有口碑

❺ 怎样用c语言编写俄罗斯方块程序

俄罗斯方块C源代码

#include<stdio.h>

#include<windows.h>

#include<conio.h>

#include<time.h>

#defineZL4 //坐标增量,不使游戏窗口靠边

#defineWID36 //游戏窗口的宽度

#defineHEI20 //游戏窗口的高度

inti,j,Ta,Tb,Tc; //Ta,Tb,Tc用于记住和转换方块变量的值

inta[60][60]={0}; //标记游戏屏幕各坐标点:0,1,2分别为空、方块、边框

intb[4]; //标记4个"口"方块:1有,0无,类似开关

intx,y,level,score,speed; //方块中心位置的x,y坐标,游戏等级、得分和游戏速度

intflag,next; //当前要操作的方块类型序号,下一个方块类型序号

voidgtxy(intm,intn); //以下声明要用到的自编函数

voidgflag(); //获得下一方块序号

voidcsh(); //初始化界面

voidstart(); //开始部分

voidprfk(); //打印方块

voidclfk(); //清除方块

voidmkfk(); //制作方块

voidkeyD(); //按键操作

intifmov(); //判断方块能否移动或变体

void clHA(); //清除满行的方块

voidclNEXT(); //清除边框外的NEXT方块

intmain()

{csh();

while(1)

{start();//开始部分

while(1)

{prfk();

Sleep(speed); //延时

clfk();

Tb=x;Tc=flag;//临存当前x坐标和序号,以备撤销操作

keyD();

y++;//方块向下移动

if(ifmov()==0){y--;prfk();dlHA();break;}//不可动放下,删行,跨出循环

}

for(i=y-2;i<y+2;i++){if(i==ZL){j=0;}} //方块触到框顶

if(j==0){system("cls");gtxy(10,10);printf("游戏结束!");getch();break;}

clNEXT(); //清除框外的NEXT方块

}

return0;

}

voidgtxy(intm,intn)//控制光标移动

{COORDpos;//定义变量

pos.X=m;//横坐标

pos.Y=n;//纵坐标

SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);

}

voidcsh()//初始化界面

{gtxy(ZL+WID/2-5,ZL-2);printf("俄罗斯方块");//打印游戏名称

gtxy(ZL+WID+3,ZL+7);printf("*******NEXT:");//打印菜单信息

gtxy(ZL+WID+3,ZL+13);printf("**********");

gtxy(ZL+WID+3,ZL+15);printf("Esc:退出游戏");

gtxy(ZL+WID+3,ZL+17);printf("↑键:变体");

gtxy(ZL+WID+3,ZL+19);printf("空格:暂停游戏");

gtxy(ZL,ZL);printf("╔");gtxy(ZL+WID-2,ZL);printf("╗");//打印框角

gtxy(ZL,ZL+HEI);printf("╚");gtxy(ZL+WID-2,ZL+HEI);printf("╝");

a[ZL][ZL+HEI]=2;a[ZL+WID-2][ZL+HEI]=2;//记住有图案

for(i=2;i<WID-2;i+=2){gtxy(ZL+i,ZL);printf("═");}//打印上横框

for(i=2;i<WID-2;i+=2){gtxy(ZL+i,ZL+HEI);printf("═");a[ZL+i][ZL+HEI]=2;}//下框

for(i=1;i<HEI;i++){gtxy(ZL,ZL+i);printf("║");a[ZL][ZL+i]=2;}//左竖框记住有图案

for(i=1;i<HEI;i++){gtxy(ZL+WID-2,ZL+i);printf("║");a[ZL+WID-2][ZL+i]=2;}//右框

CONSOLE_CURSOR_INFOcursor_info={1,0};//以下是隐藏光标的设置

SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info);

level=1;score=0;speed=400;

gflag();flag=next;//获得一个当前方块序号

}

voidgflag() //获得下一个方块的序号

{srand((unsigned)time(NULL));next=rand()%19+1; }

voidstart()//开始部分

{gflag();Ta=flag;flag=next;//保存当前方块序号,将下一方块序号临时操作

x=ZL+WID+6;y=ZL+10;prfk();//给x,y赋值,在框外打印出下一方块

flag=Ta;x=ZL+WID/2;y=ZL-1;//取回当前方块序号,并给x,y赋值

}

voidprfk()//打印俄罗斯方块

{for(i=0;i<4;i++){b[i]=1;}//数组b[4]每个元素的值都为1

mkfk();//制作俄罗斯方块

for(i=x-2;i<=x+4;i+=2)//打印方块

{for(j=y-2;j<=y+1;j++){if(a[i][j]==1&&j>ZL){gtxy(i,j);printf("□");}}}

gtxy(ZL+WID+3,ZL+1); printf("level:%d",level); //以下打印菜单信息

gtxy(ZL+WID+3,ZL+3); printf("score:%d",score);

gtxy(ZL+WID+3,ZL+5); printf("speed:%d",speed);

}

voidclfk()//清除俄罗斯方块

{for(i=0;i<4;i++){b[i]=0;}//数组b[4]每个元素的值都为0

mkfk();//制作俄罗斯方块

for(i=x-2;i<=x+4;i+=2)//清除方块

{for(j=y-2;j<=y+1;j++){if(a[i][j]==0&&j>ZL){gtxy(i,j);printf("");}}}

}

voidmkfk()//制作俄罗斯方块

{a[x][y]=b[0];//方块中心位置状态:1-有,0-无

switch(flag)//共6大类,19种小类型

{case1:{a[x][y-1]=b[1];a[x+2][y-1]=b[2];a[x+2][y]=b[3];break;}//田字方块

case2:{a[x-2][y]=b[1];a[x+2][y]=b[2];a[x+4][y]=b[3];break;}//直线方块:----

case3:{a[x][y-1]=b[1];a[x][y-2]=b[2];a[x][y+1]=b[3];break;}//直线方块:|

case4:{a[x-2][y]=b[1];a[x+2][y]=b[2];a[x][y+1]=b[3];break;}//T字方块

case5:{a[x][y-1]=b[1];a[x][y+1]=b[2];a[x-2][y]=b[3];break;}//T字顺时针转90度

case6:{a[x][y-1]=b[1];a[x-2][y]=b[2];a[x+2][y]=b[3];break;}//T字顺转180度

case7:{a[x][y-1]=b[1];a[x][y+1]=b[2];a[x+2][y]=b[3];break;}//T字顺转270度

case8:{a[x][y+1]=b[1];a[x-2][y]=b[2];a[x+2][y+1]=b[3];break;}//Z字方块

case9:{a[x][y-1]=b[1];a[x-2][y]=b[2];a[x-2][y+1]=b[3];break;}//Z字顺转90度

case10:{a[x][y-1]=b[1];a[x-2][y-1]=b[2];a[x+2][y]=b[3];break;}//Z字顺转180度

case11:{a[x][y+1]=b[1];a[x+2][y-1]=b[2];a[x+2][y]=b[3];break;}//Z字顺转270度

case12:{a[x][y-1]=b[1];a[x][y+1]=b[2];a[x-2][y-1]=b[3];break;}//7字方块

case13:{a[x-2][y]=b[1];a[x+2][y-1]=b[2];a[x+2][y]=b[3];break;}//7字顺转90度

case14:{a[x][y-1]=b[1];a[x][y+1]=b[2];a[x+2][y+1]=b[3];break;}//7字顺转180度

case15:{a[x-2][y]=b[1];a[x-2][y+1]=b[2];a[x+2][y]=b[3];break;}//7字顺转270度

case16:{a[x][y+1]=b[1];a[x][y-1]=b[2];a[x+2][y-1]=b[3];break;}//倒7字方块

case17:{a[x-2][y]=b[1];a[x+2][y+1]=b[2];a[x+2][y]=b[3];break;}//倒7字顺转90度

case18:{a[x][y-1]=b[1];a[x][y+1]=b[2];a[x-2][y+1]=b[3];break;}//倒7字顺转180度

case19:{a[x-2][y]=b[1];a[x-2][y-1]=b[2];a[x+2][y]=b[3];break;}//倒7字顺转270度

}

}

voidkeyD()//按键操作

{if(kbhit())

{intkey;

key=getch();

if(key==224)

{key=getch();

if(key==75){x-=2;}//按下左方向键,中心横坐标减2

if(key==77){x+=2;}//按下右方向键,中心横坐标加2

if(key==72)//按下向上方向键,方块变体

{if(flag>=2&&flag<=3){flag++;flag%=2;flag+=2;}

if(flag>=4&&flag<=7){flag++;flag%=4;flag+=4;}

if(flag>=8&&flag<=11){flag++;flag%=4;flag+=8;}

if(flag>=12&&flag<=15){flag++;flag%=4;flag+=12;}

if(flag>=16&&flag<=19){flag++;flag%=4;flag+=16;}}

}

if(key==32)//按空格键,暂停

{prfk();while(1){if(getch()==32){clfk();break;}}} //再按空格键,继续游戏

if(ifmov()==0){x=Tb;flag=Tc;} //如果不可动,撤销上面操作

else{prfk();Sleep(speed);clfk();Tb=x;Tc=flag;} //如果可动,执行操作

}

}

intifmov()//判断能否移动

{if(a[x][y]!=0){return0;}//方块中心处有图案返回0,不可移动

else{if((flag==1&&(a[x][y-1]==0&&a[x+2][y-1]==0&&a[x+2][y]==0))||

(flag==2&&(a[x-2][y]==0&&a[x+2][y]==0&&a[x+4][y]==0))||

(flag==3&&(a[x][y-1]==0&&a[x][y-2]==0&&a[x][y+1]==0))||

(flag==4&&(a[x-2][y]==0&&a[x+2][y]==0&&a[x][y+1]==0))||

(flag==5&&(a[x][y-1]==0&&a[x][y+1]==0&&a[x-2][y]==0))||

(flag==6&&(a[x][y-1]==0&&a[x-2][y]==0&&a[x+2][y]==0))||

(flag==7&&(a[x][y-1]==0&&a[x][y+1]==0&&a[x+2][y]==0))||

(flag==8&&(a[x][y+1]==0&&a[x-2][y]==0&&a[x+2][y+1]==0))||

(flag==9&&(a[x][y-1]==0&&a[x-2][y]==0&&a[x-2][y+1]==0))||

(flag==10&&(a[x][y-1]==0&&a[x-2][y-1]==0&&a[x+2][y]==0))||

(flag==11&&(a[x][y+1]==0&&a[x+2][y-1]==0&&a[x+2][y]==0))||

(flag==12&&(a[x][y-1]==0&&a[x][y+1]==0&&a[x-2][y-1]==0))||

( flag==13 && ( a[x-2][y]==0 && a[x+2][y-1]==0 && a[x+2][y]==0 ) ) ||

( flag==14 && ( a[x][y-1]==0 && a[x][y+1]==0 && a[x+2][y+1]==0 ) ) ||

(flag==15 && ( a[x-2][y]==0 && a[x-2][y+1]==0 && a[x+2][y]==0 ) ) ||

(flag==16 && ( a[x][y+1]==0 && a[x][y-1]==0 && a[x+2][y-1]==0 ) ) ||

( flag==17 && ( a[x-2][y]==0 && a[x+2][y+1]==0 && a[x+2][y]==0 ) ) ||

(flag==18 && ( a[x][y-1]==0 &&a[x][y+1]==0 && a[x-2][y+1]==0 ) ) ||

(flag==19 && ( a[x-2][y]==0 && a[x-2][y-1]==0

&&a[x+2][y]==0))){return1;}

}

return0; //其它情况返回0

}

voidclNEXT() //清除框外的NEXT方块

{flag=next;x=ZL+WID+6;y=ZL+10;clfk();}

void clHA() //清除满行的方块

{intk,Hang=0; //k是某行方块个数,Hang是删除的方块行数

for(j=ZL+HEI-1;j>=ZL+1;j--)//当某行有WID/2-2个方块时,则为满行

{k=0;for(i=ZL+2;i<ZL+WID-2;i+=2)

{if(a[i][j]==1)//竖坐标从下往上,横坐标由左至右依次判断是否满行

{k++; //下面将操作删除行

if(k==WID/2-2) { for(k=ZL+2;k<ZL+WID-2;k+=2)

{a[k][j]=0;gtxy(k,j);printf("");Sleep(1);}

for(k=j-1;k>ZL;k--)

{for(i=ZL+2;i<ZL+WID-2;i+=2)//已删行数上面有方块,先清除再全部下移一行

{if(a[i][k]==1){a[i][k]=0;gtxy(i,k);printf("");a[i][k+1]=1;

gtxy(i,k+1);printf("□");}}

}

j++;//方块下移后,重新判断删除行是否满行

Hang++;//记录删除方块的行数

}

}

}

}

score+=100*Hang; //每删除一行,得100分

if(Hang>0&&(score%500==0||score/500>level-1)) //得分满500速度加快升一级

{speed-=20;level++;if(speed<200)speed+=20; }

}

❻ 高分征求有详细注解的俄罗斯方块C语言源代码。

#include <stdio.h>
#include <银扰dos.h>
#include <conio.h>扰滑
#include <graphics.h>
#include <stdlib.h>

#ifdef __cplusplus
#define __CPPARGS ...
#else
#define __CPPARGS
#endif
#define MINBOXSIZE 15 /* 最小方块的尺寸 */
#define BGCOLOR 7 /* 背景着色 */
#define GX 200
#define GY 10
#define SJNUM 10000 /* 每当玩家打到一万分等级加一级*/

/* 按键码*/
#define VK_LEFT 0x4b00
#define VK_RIGHT 0x4d00
#define VK_DOWN 0x5000
#define VK_UP 0x4800
#define VK_HOME 0x4700
#define VK_END 0x4f00
#define VK_SPACE 0x3920
#define VK_ESC 0x011b
#define VK_ENTER 0x1c0d

/* 定义俄罗斯方块的方向(我定义他为4种)*/
#define F_DONG 0
#define F_NAN 1
#define F_XI 2
#define F_BEI 3

#define NEXTCOL 20 /* 要出的下一个方块的纵坐标*/
#define NEXTROW 12 /* 要出的下一个方块的横从标*/
#define MAXROW 14 /* 游戏屏幕大小*/
#define MAXCOL 20
#define SCCOL 100 /*游戏屏幕大显示器上的相对位置*/
#define SCROW 60

int gril[22][16]; /* 游戏屏幕坐标*/
int col=1,row=7; /* 当前方块的横纵坐标*/
int boxfx=0,boxgs=0; /* 当前寺块的形壮和方向*/
int nextboxfx=0,nextboxgs=0,maxcol=22;/*下一个方块的形壮和方向*/
int minboxcolor=6,nextminboxcolor=6;
int num=0; /*游戏分*/
int dj=0,gamedj[10]={18,16,14,12,10,8,6,4,2,1};/* 游戏等级*/
/* 以下我用了一个3维数组来纪录方块的最初形状和缓搏腊方向*/
int boxstr[7][4][16]={{
{1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0},
{0,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0},
{1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0},
{0,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0}},
{
{0,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0},
{1,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0},
{0,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0},
{1,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0}},
{
{1,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0},
{1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0},
{1,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0},
{0,0,1,0,1,1,1,0,0,0,0,0,0,0,0,0}},
{
{1,1,0,0,1,0,0,0,1,0,0,0,0,0,0,0},
{1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0},
{0,1,0,0,0,1,0,0,1,1,0,0,0,0,0,0},
{1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0}},
{
{0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0},
{0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0},
{0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0},
{0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0}},
{
{1,1,0,0,1,1,0,0,0,0,0,0.0,0,0,0},
{1,1,0,0,1,1,0,0,0,0,0,0.0,0,0,0},
{1,1,0,0,1,1,0,0,0,0,0,0.0,0,0,0},
{1,1,0,0,1,1,0,0,0,0,0,0.0,0,0,0}},
{
{0,0,0,0,1,1,1,0,0,1,0,0,0,0,0,0},
{1,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0},
{0,1,0,0,1,1,1,0,0,0,0,0.0,0,0,0},
{0,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0}}

};

/* 随机得到当前方块和下一个方块的形状和方向*/
void boxrad(){
minboxcolor=nextminboxcolor;
boxgs=nextboxgs;
boxfx=nextboxfx;
nextminboxcolor=random(14)+1;
if(nextminboxcolor==4||nextminboxcolor==7||nextminboxcolor==8)
nextminboxcolor=9;
nextboxfx=F_DONG;
nextboxgs=random(7);
}
/*初始化图形模试*/
void init(int gdrive,int gmode){
int errorcode;
initgraph(&gdrive,&gmode,"D:\\tc\\");
errorcode=graphresult();
if(errorcode!=grOk){
printf("error of: %s",grapherrormsg(errorcode));
exit(1);
}
}

/* 在图形模式下的清屏 */
void cls()
{
setfillstyle(SOLID_FILL,0);
setcolor(0);
bar(0,0,640,480);
}
/*在图形模式下的高级清屏*/
void clscr(int a,int b,int c,int d,int color){
setfillstyle(SOLID_FILL,color);
setcolor(color);
bar(a,b,c,d);
}
/*最小方块的绘制*/
void minbox(int asc,int bsc,int color,int bdcolor){
int a=0,b=0;
a=SCCOL+asc;
b=SCROW+bsc;
clscr(a+1,b+1,a-1+MINBOXSIZE,b-1+MINBOXSIZE,color);
if(color!=BGCOLOR){
setcolor(bdcolor);
line(a+1,b+1,a-1+MINBOXSIZE,b+1);
line(a+1,b+1,a+1,b-1+MINBOXSIZE);
line(a-1+MINBOXSIZE,b+1,a-1+MINBOXSIZE,b-1+MINBOXSIZE);
line(a+1,b-1+MINBOXSIZE,a-1+MINBOXSIZE,b-1+MINBOXSIZE);
}
}

/*游戏中出现的文字*/
void txt(int a,int b,char *txt,int font,int color){
setcolor(color);
settextstyle(0,0,font);
outtextxy(a,b,txt);
}
/*windows 绘制*/
void win(int a,int b,int c,int d,int bgcolor,int bordercolor){
clscr(a,b,c,d,bgcolor);
setcolor(bordercolor);
line(a,b,c,b);
line(a,b,a,d);
line(a,d,c,d);
line(c,b,c,d);

}

/* 当前方块的绘制*/
void funbox(int a,int b,int color,int bdcolor){
int i,j;
int boxz[4][4];
for(i=0;i<16;i++)
boxz[i/4][i%4]=boxstr[boxgs][boxfx][i];
for(i=0;i<4;i++)
for(j=0;j<4;j++)
if(boxz[i][j]==1)
minbox((j+row+a)*MINBOXSIZE,(i+col+b)*MINBOXSIZE,color,bdcolor);
}
/*下一个方块的绘制*/
void nextfunbox(int a,int b,int color,int bdcolor){
int i,j;
int boxz[4][4];
for(i=0;i<16;i++)
boxz[i/4][i%4]=boxstr[nextboxgs][nextboxfx][i];
for(i=0;i<4;i++)
for(j=0;j<4;j++)
if(boxz[i][j]==1)
minbox((j+a)*MINBOXSIZE,(i+b)*MINBOXSIZE,color,bdcolor);
}
/*时间中断定义*/
#define TIMER 0x1c
int TimerCounter=0;
void interrupt ( *oldhandler)(__CPPARGS);
void interrupt newhandler(__CPPARGS){
TimerCounter++;
oldhandler();
}
void SetTimer(void interrupt (*IntProc)(__CPPARGS)){
oldhandler=getvect(TIMER);
disable();
setvect(TIMER,IntProc);
enable();
}
/*由于游戏的规则,消掉都有最小方块的一行*/
void delcol(int a){
int i,j;
for(i=a;i>1;i--)
for(j=1;j<15;j++){
minbox(j*MINBOXSIZE,i*MINBOXSIZE,BGCOLOR,BGCOLOR);
gril[i][j]=gril[i-1][j];
if(gril[i][j]==1)
minbox(j*MINBOXSIZE,i*MINBOXSIZE,minboxcolor,0);
}
}

/*消掉所有都有最小方块的行*/
void delete(){
int i,j,zero,delgx=0;
char *nm="00000";
for(i=1;i<21;i++){
zero=0;
for(j=1;j<15;j++)
if(gril[i][j]==0)
zero=1;
if(zero==0){
delcol(i);
delgx++;
}
}
num=num+delgx*delgx*10;
dj=num/10000;

sprintf(nm,"%d",num);
clscr(456,173,500,200,4);
txt(456,173,"Number:",1,15);
txt(456,193,nm,1,15);
}
/*时间中断结束*/
void KillTimer(){
disable();
setvect(TIMER,oldhandler);
enable();
}
/* 测试当前方块是否可以向下落*/
int downok(){
int i,j,k=1,a[4][4];
for(i=0;i<16;i++)
a[i/4][i%4]=boxstr[boxgs][boxfx][i];
for(i=0;i<4;i++)
for(j=0;j<4;j++)
if(a[i][j] && gril[col+i+1][row+j])
k=0;
return(k);
}
/* 测试当前方块是否可以向左行*/
int leftok(){
int i,j,k=1,a[4][4];
for(i=0;i<16;i++)
a[i/4][i%4]=boxstr[boxgs][boxfx][i];
for(i=0;i<4;i++)
for(j=0;j<4;j++)
if(a[i][j] && gril[col+i][row+j-1])
k=0;
return(k);
}
/* 测试当前方块是否可以向右行*/
int rightok(){
int i,j,k=1,a[4][4];
for(i=0;i<16;i++)
a[i/4][i%4]=boxstr[boxgs][boxfx][i];
for(i=0;i<4;i++)
for(j=0;j<4;j++)
if(a[i][j] && gril[col+i][row+j+1])
k=0;
return(k);
}
/* 测试当前方块是否可以变形*/
int upok(){
int i,j,k=1,a[4][4];
for(i=0;i<4;i++)
for(i=0;i<16;i++)
a[i/4][i%4]=boxstr[boxgs][boxfx+1][i];
for(i=3;i>=0;i--)
for(j=3;j>=0;j--)
if(a[i][j] && gril[col+i][row+j])
k=0;
return(k);
}
/*当前方块落下之后,给屏幕坐标作标记*/
void setgril(){
int i,j,a[4][4];
funbox(0,0,minboxcolor,0);
for(i=0;i<16;i++)
a[i/4][i%4]=boxstr[boxgs][boxfx][i];
for(i=0;i<4;i++)
for(j=0;j<4;j++)
if(a[i][j])
gril[col+i][row+j]=1;
col=1;row=7;
}
/*游戏结束*/
void gameover(){
int i,j;

for(i=20;i>0;i--)
for(j=1;j<15;j++)
minbox(j*MINBOXSIZE,i*MINBOXSIZE,2,0);
txt(103,203,"Game Over",3,10);
}
/*按键的设置*/
void call_key(int keyx){
switch(keyx){
case VK_DOWN: { /*下方向键,横坐标加一。*/
if(downok()){
col++;
funbox(0,0,minboxcolor,0);}
else{
funbox(0,0,minboxcolor,0);
setgril();
nextfunbox(NEXTCOL,NEXTROW,4,4);
boxrad();
nextfunbox(NEXTCOL,NEXTROW,nextminboxcolor,0);
delete();
}
break;
}
case VK_UP: { /*上方向键,方向形状旋转90度*/
if(upok())
boxfx++;
if(boxfx>3)
boxfx=0;
funbox(0,0,minboxcolor,0);
break;
}
case VK_LEFT:{ /*左方向键,纵坐标减一*/
if(leftok())
row--;
funbox(0,0,minboxcolor,0);
break;
}
case VK_RIGHT:{ /*右方向键,纵坐标加一*/
if(rightok())
row++;
funbox(0,0,minboxcolor,0);
break;
}
case VK_SPACE: /*空格键,直接落到最后可以落到的们置*/
while(downok())
col++;
funbox(0,0,minboxcolor,0);
setgril();
nextfunbox(NEXTCOL,NEXTROW,4,4);
boxrad();
nextfunbox(NEXTCOL,NEXTROW,nextminboxcolor,0);
delete();
break;
default:
{
txt(423,53,"worng key!",1,4);
txt(428,80,"Plese Enter Anly Key AG!",1,4);
getch();
clscr(420,50,622,97,BGCOLOR);
}
}
}

/*时间中断开始*/
void timezd(void){
int key;
SetTimer(newhandler);
boxrad();
nextfunbox(NEXTCOL,NEXTROW,nextminboxcolor,0);
for(;;){
if(bioskey(1)){
key=bioskey(0);
funbox(0,0,BGCOLOR,BGCOLOR);
if(key==VK_ESC)
break;
call_key(key);
}
if(TimerCounter>gamedj[dj]){
TimerCounter=0;
if(downok()){
funbox(0,0,BGCOLOR,BGCOLOR);
col++;
funbox(0,0,minboxcolor,0);
}
else {
if(col==1){
gameover();
getch();
break;
}
setgril();
delete();
funbox(0,0,minboxcolor,0);
col=1;row=7;
funbox(0,0,BGCOLOR,BGCOLOR);
nextfunbox(NEXTCOL,NEXTROW,4,4);
boxrad();
nextfunbox(NEXTCOL,NEXTROW,nextminboxcolor,0);
}
}
}
}

/*主程序开始*/
void main(void){
int i,j;
char *nm="00000";
init(VGA,VGAHI);
cls();
/*屏幕坐标初始化*/
for(i=0;i<=MAXCOL+1;i++)
for(j=0;j<=MAXROW+1;j++)
gril[i][j]=0;
for(i=0;i<=MAXCOL+1;i++) {
gril[i][0]=1;
gril[i][15]=1;
}
for(j=1;j<=MAXROW;j++){
gril[0][j]=1;
gril[21][j]=1;
}
clscr(0,0,640,480,15);
win(1,1,639,479,4,15);
win(SCCOL+MINBOXSIZE-2,SCROW+MINBOXSIZE-2,SCCOL+15*MINBOXSIZE+2,SCROW+21*MINBOXSIZE+2,BGCOLOR,0);
nextboxgs=random(8);
nextboxfx=random(4);
sprintf(nm,"%d",num);
txt(456,173,"Number:",1,15);
txt(456,193,nm,1,15);
txt(456,243,"Next Box:",1,15);
timezd();
KillTimer();
closegraph();
}

热点内容
3nvm服务器怎么搭建 发布:2025-02-05 17:43:52 浏览:660
cocosandroid开发 发布:2025-02-05 17:22:17 浏览:667
编程员发型 发布:2025-02-05 17:09:18 浏览:225
网站会员管理源码 发布:2025-02-05 17:03:32 浏览:193
服务器端口怎么调节 发布:2025-02-05 16:57:41 浏览:46
乐山海棠社区民意上传 发布:2025-02-05 16:55:52 浏览:510
编程老爷爷 发布:2025-02-05 16:48:20 浏览:129
支持ftp的免费空间 发布:2025-02-05 16:32:00 浏览:891
python时间比较 发布:2025-02-05 16:31:46 浏览:52
手机银行的密码怎么改密码忘了怎么办啊 发布:2025-02-05 16:02:02 浏览:181