C语言俄罗斯方块

article/2025/9/23 2:12:51

C语言俄罗斯方块

先看效果

在这里插入图片描述在这里插入图片描述

代码如下

/************************************** 俄罗斯方块* 1. 游戏开始界面,显示界面* 2. 方块的产生,及判断方块产生的位置是否有方块,有就退出游戏* 3. 方块的移动,旋转,左右移动,是否能移动* 4. 方块到底,是否满行,产生新的方块* @author zhoufei* @date 2018-6-24
***************************************/
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#define UI_WIDTH 14 //显示界面的宽度
#define UI_HEIGHT 25 //界面的高度
#define WALL 1
#define BLOCK 2
#define VK_UP 72   //方向键上下左右的第二个值,方向键有两个值,第一个是224,分别是72,...
#define VK_DOWN 80
#define VK_LEFT 75
#define VK_RIGHT 77
#define TRUE 1
#define FALSE 0
void initia();			//初始化的一些工作
void gameShow(); 	/*游戏显示界面*/
void moveBlock(); 	/*方块的移动*/
short isCanMoveBlock(short x, short y); 	//是否能移动方块
void produceBlock();   //产生方块
void toBottom(short x, short y);				//方块到底了之后的操作 ,bottom:底
short cur_block_coord_x ,cur_block_coord_y; //当前方块的横坐标及纵坐标
//int game_arr[UI_HEIGHT][UI_WIDTH]; //游戏的界面数组
short next_blockarr[4][4];			//用来存放下一个方块的数组
short cur_boxindex,next_boxindex; //记录当前方块的下标和下一个方块的下标
int score;  //成绩
char player_name[10] = "你大哥" ;    //玩家的姓名
HANDLE hOutput;
struct _game_arr{short info;  //用来存放游戏界面的数组short  var;  //用来记录该数组的某个位置是否被占用 ,当方块没有移动了,//该位置才被占用,当移动方块是那个地方被占用就不能移动了 ,用1表示占用,0表示未占用
}game_arr[UI_HEIGHT][UI_WIDTH];
struct _block
{short a[4][2]; /*定义方块形状的数组,每个方块共有4个小块组成,用4行2列来记录每个小方块的相对 坐标, */short next; //下一个方块的号码
};
struct _block block[19]=
{  //初始化各个游戏方块, 总共有19总方块形状{1,1,1,2,1,3,2,3,1},{0,2,1,2,2,2,0,3,2},{0,1,1,1,1,2,1,3,3},{2,1,0,2,1,2,2,2,0},{1,1,1,2,0,3,1,3,5},{0,1,0,2,1,2,2,2,6},{1,1,2,1,1,2,1,3,7},{0,2,1,2,2,2,2,3,4},{1,1,0,2,1,2,2,2,9},{1,1,1,2,2,2,1,3,10},{0,2,1,2,2,2,1,3,11},{1,1,0,2,1,2,1,3,8},{1,1,1,2,2,2,2,3,13},{1,2,2,2,0,3,1,3,12},{2,1,1,2,2,2,1,3,15},{0,2,1,2,1,3,2,3,14},{1,0,1,1,1,2,1,3,17},{0,2,1,2,2,2,3,2,16},{1,1,2,1,1,2,2,2,18},
};
void main()
{hOutput = GetStdHandle(STD_OUTPUT_HANDLE);SetConsoleTitle(TEXT("俄罗斯方块"));SMALL_RECT rc =  {0,0,UI_WIDTH*2+15,UI_HEIGHT+3};  //设置窗口大小,宽度和高度SetConsoleWindowInfo(hOutput,TRUE,&rc);srand(time(NULL));initia();//隐藏缓冲区的光标CONSOLE_CURSOR_INFO cci;cci.bVisible = 0;cci.dwSize =1;SetConsoleCursorInfo(hOutput, &cci);produceBlock();moveBlock();
}
void initia()
{//初始化的一些工作short i,j;for(i = 0; i < UI_HEIGHT; i++){for(j = 0; j < UI_WIDTH; j++){if(i == 0 || i == UI_HEIGHT-1) {game_arr[i][j].info = WALL; game_arr[i][j].var = 1;continue;}  //.var=1表示该点被占用if(j == 0 || j == UI_WIDTH-1)  {game_arr[i][j].info = WALL; game_arr[i][j].var = 1;continue;}}}printf("\n\n\t欢迎你的到来\n\t请您输入一个昵称吧!>:");scanf("%s",&player_name);next_boxindex =  rand() % 19;	 //第一次要随机产生两个方块
}
/*游戏显示界面*/
void gameShow()
{//1显示边框,空格,方块short i,j;system("cls");puts("\n\t\t<俄罗斯方块>");for(i = 0; i < UI_HEIGHT; i++){for(j = 0; j < UI_WIDTH; j++){if(game_arr[i][j].info == 0) {printf("+");continue;}if(game_arr[i][j].info == WALL){if(i == 0 || i == UI_HEIGHT-1) printf("-");//画横else printf("|"); continue;}if(game_arr[i][j].info == BLOCK) printf("▉");}if(i == 1)  printf("  下一个方块");if(i >= 2 && i <= 5) //下一个方块{printf("  ");for(j = 0; j < 4; j++){if(next_blockarr[i-2][j] == 0) printf("  "); //要减2,因为从i事从2开始的else printf("▉");}}if(i == 10) printf("  玩家:%s",player_name);if(i == 11) printf("  得分:%d",score);if(i == UI_HEIGHT-6) printf("  操作");if(i == UI_HEIGHT-5) printf("  ↑旋转");if(i == UI_HEIGHT-4) printf("  ←左移");if(i == UI_HEIGHT-3) printf("  →右移");if(i == UI_HEIGHT-2) printf("  ↓下移");printf("\n");}
}
/*每一个方块的产生*/
void produceBlock()
{//在游戏界面的中间放置方块short i,j;cur_boxindex = next_boxindex;next_boxindex = rand() % 19; //方块的编号随机产生cur_block_coord_x = (UI_WIDTH-2)/2; //从中间落下cur_block_coord_y = 1;for(i = 0; i < 4; i++)for(j = 0; j < 4; j++)next_blockarr[i][j] = 0; //每次产生新的方块,都要将存放下一个方块的数组清零for(i = 0; i < 4; i++){game_arr[cur_block_coord_y+block[cur_boxindex].a[i][1]][cur_block_coord_x+block[cur_boxindex].a[i][0]].info = BLOCK ;next_blockarr[block[next_boxindex].a[i][1]][block[next_boxindex].a[i][0]] = BLOCK;}if( !isCanMoveBlock(cur_block_coord_x,cur_block_coord_y))  //产生新方块的这个地方被占用了,退出{printf("游戏结束,再接再厉!");getch();exit(0);}
}
/*方块的移动*/
void moveBlock()
{short i,j,to_bottom = FALSE;	//到底short old_x = cur_block_coord_x,old_y = cur_block_coord_y; //用来记录旧的方块的位置short old_boxindex = cur_boxindex;    //记录方块的下标,按上键时改变方块用while(1){old_x = cur_block_coord_x,old_y = cur_block_coord_y;old_boxindex = cur_boxindex;while(kbhit())  //用户按键{  // getch();switch(getch()){case VK_UP:   cur_boxindex = block[cur_boxindex].next;if(!isCanMoveBlock(cur_block_coord_x, cur_block_coord_y))cur_boxindex =	old_boxindex;  //如果不能旋转的话要还原break;case VK_DOWN: for(i = 0; i < 4; i++) //一次可以下降4个if(isCanMoveBlock(cur_block_coord_x, cur_block_coord_y + 1)) cur_block_coord_y++;else  {to_bottom = TRUE;break;}//到底break;case VK_LEFT:  if(isCanMoveBlock(cur_block_coord_x - 1, cur_block_coord_y)) cur_block_coord_x--;break;case VK_RIGHT: if(isCanMoveBlock(cur_block_coord_x + 1, cur_block_coord_y)) cur_block_coord_x++;break;}}if(to_bottom){if(old_x != cur_block_coord_x || old_y != cur_block_coord_y || old_boxindex != cur_boxindex){for(i = 0;i < 4; i++)game_arr[old_y+block[old_boxindex].a[i][1]][old_x+block[old_boxindex].a[i][0]].info = 0;for(i = 0;i < 4; i++)game_arr[cur_block_coord_y+block[cur_boxindex].a[i][1]][cur_block_coord_x+block[cur_boxindex].a[i][0]].info = BLOCK;gameShow();  //要按键之后才刷新}to_bottom = FALSE; toBottom(cur_block_coord_x, cur_block_coord_y);gameShow();//到底}else{if(j++ % 10 == 0)  //自动下移,要放前面,{if(isCanMoveBlock(cur_block_coord_x, cur_block_coord_y + 1)) cur_block_coord_y++;else  to_bottom = TRUE; //到底}if(old_x != cur_block_coord_x || old_y != cur_block_coord_y || old_boxindex != cur_boxindex){for(i = 0;i < 4; i++)game_arr[old_y+block[old_boxindex].a[i][1]][old_x+block[old_boxindex].a[i][0]].info = 0;for(i = 0;i < 4; i++)game_arr[cur_block_coord_y+block[cur_boxindex].a[i][1]][cur_block_coord_x+block[cur_boxindex].a[i][0]].info = BLOCK;gameShow();  //要按键之后才刷新}}Sleep(20);}
}
short isCanMoveBlock(short x, short y)
{//是否能移动方块short i;for(i=0;i<4;i++)if(game_arr[y+block[cur_boxindex].a[i][1]][x+block[cur_boxindex].a[i][0]].var)return FALSE;	//如果该位置以及有方块填充,则不能移动return TRUE;
}
void toBottom(short x, short y)
{	//方块到底之后的操作,1.将方块的位置的状态变为1,表示被占用。2.是否满块,消行,改变状态 3.产生新的方块short i,j;for(i = 0; i < 4; i++)game_arr[y+block[cur_boxindex].a[i][1]][x+block[cur_boxindex].a[i][0]].var = 1;//2.是否满块,消行,改变状态for(i = UI_HEIGHT - 2; i >= 1; i--) //有两行是墙 ,从底开始往上搜{for(j = 1; j <= UI_WIDTH - 2; j++){if( !game_arr[i][j].var)break;//一行有空的就跳出这个循环 ,继续搜下一行if(j == UI_WIDTH - 2) 	//一行都满了,消行,此时第i行是满行{score += 10;	int h,v;for(v = i; v >= 2; v--) //第i行开始,{for(h = 1; h <= UI_WIDTH - 2; h++){game_arr[v][h].info = game_arr[v-1][h].info;game_arr[v][h].var = game_arr[v-1][h].var;}}//要从底行重新,之后i--,i =  UI_HEIGHT - 2,就会出现多行一起消时有行消不了i = UI_HEIGHT - 1;}}}produceBlock();
}

http://chatgpt.dhexx.cn/article/eoAchDZm.shtml

相关文章

C语言小游戏快速入门--弹跳小球

目录 一、前言二、弹跳小球的实现2.1、界面设置2.2、弹跳逻辑1、 game.h2、 game.c3、 test.c 三、总结 一、前言 相信很多小伙伴在学习完C语言语法之后就想要做几个小游戏&#xff0c;来练练手。弹跳小球就很适合C语言初学者&#xff0c;甚至你不需要学习到数组的知识就可以上…

【C语言】简单小游戏项目:《别踩白块儿》

序 突然喜欢惊鸿一瞥这个词&#xff0c;一见钟情太肤浅日久生情太苍白&#xff0c;别人眉来眼去&#xff0c;我只偷偷看你一眼。 嗨&#xff01;这里是狐狸~ 新的一周又开始了&#xff0c;时间过得还真快&#xff0c;不知道给大家分享点啥了&#xff0c;想发偏算法之类怕大家…

【C语言小游戏】走迷宫

偶然翻到了自己大一时候写的一些代码&#xff0c;代码冗余&#xff0c;但还是想保存下来&#xff0c;以作纪念。 文章目录 1.运行效果2.运行环境3.完整代码 1.运行效果 2.运行环境 源码(Dev5.4.0版本下可直接(.cpp文件)运行 gcc 4.7.2) 注意&#xff1a;由于部分代码为C11标准&…

C语言小游戏------贪吃蛇----小白专用

C语言贪吃蛇小游戏 视频正在随缘策划中。。。。 废话在后面直接上程序 该程序在VS2019上可完美运行。 #include<stdio.h> #include<stdlib.h> #include<Windows.h> #include<time.h> #include<conio.h> constexpr auto maphigh 28, mapwid…

bootstrap时间控件--时间选择器

对应上面的三个时间选择器&#xff0c;写法如下&#xff1a; 首先引入css和js&#xff1a; <link href"https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel"stylesheet"> <link href"https://cdn.bootcss.com/bootstrap-…

日期时间控件

标题 开发软件使用到日期时间控件的地方很多&#xff0c;但是很多时候Html5自带的时间控件无法满足开发的需要&#xff0c;所以使用这种时间控件完全没有问题 引用 很多时候我们开发引用别人的控件时候&#xff0c;发现老是出现错误&#xff0c;是因为我们引用出现错误&#x…

时间控件(Time Control)

之前在网上看时间控件&#xff0c;看到这个http://hi.baidu.com/fxh19860822/blog/item/dd17d923343556ae4623e8e9.html&#xff0c;感觉颜色蛮好的&#xff0c;后来觉得要是时针、分针、秒针也可以供用户交互就更好了&#xff0c;不管怎样&#xff0c;有了idea就试试吧。 老规…

时间日期选择控件

这篇blog带来一个感觉不错的时间日期选择控件&#xff0c;当然&#xff0c;该控件也可以自定义选项内容。但这里主要说下时间选择的功能&#xff01; github地址 跟着大神的脚步&#xff0c;总有一天会成为神&#xff01; 效果&#xff1a; 关键点&#xff1a; 该控件可以…

jqueryUI日期控件和时间控件

日期控件用法&#xff1a; <!DOCTYPE html> <head><meta charset"utf-8"><title>日期</title><link rel"stylesheet" href"css/jquery-ui.css"><script src"js/jquery-3.3.1.min.js"><…

Timer时间控件

第一步、创建一个Windows窗体&#xff0c; 第二步、创建样式&#xff0c;在工具箱中找到TextBox和Labell、Button、timer。 第三步、改变属性的Name和 Text&#xff08;就是改写名称&#xff09; 第四步、排版按钮 1&#xff1a;使用的控制器是Label&#xff1b;name改为lbl…

web前端时间控件使用

官方参考地址&#xff1a;http://www.layui.com/laydate/ 1.首先把下载的layDate文件夹放入项目目录下 2.在需要使用的页面引入/layDate/laydate.js 3.创建input并使用js初始化input&#xff0c;获取选择时间值时只需获取input的value即可 官方实例&#xff1a; 生成效果&a…

时间日期控件的使用

在Android中&#xff0c;时间日期控件相对来说还是比较丰富的。其中&#xff0c;DatePicker用来实现日期输入设置&#xff0c;TimePicker用来实现时间输入设置。DatePickerDialog用来显示日期对话框&#xff0c;TimePickerDialog用来显示时间对话框。AnalogClock用来显示一个指…

Android中日期和时间控件的使用

本文主要讲述Android中的日期控件和时间控件的使用&#xff0c;以一个Demo的例子来展示日期和时间控件的使用&#xff0c;先看下如下效果图&#xff1a; 从效果图中可以看到该Demo是通过单击【选择日期】按钮和【选择时间】按钮弹出日期或者时间的对话框&#xff0c;然后设置日…

前端时间控件

1.My97 Datepicker js引入&input标签编写 <script type"text/javascript" src"<%request.getContextPath() %>/js/My97DatePicker/WdatePicker.js"></script> <input style"width: 80%" id"showStartDate&quo…

Android开发之日期时间控件选择

Android开发之日期时间控件选择 文章目录 前言一、创建弹出Layout1.1 新建Layout&#xff0c;修改样式为LinearLayout1.2 Layout中添加日期和时间控件 二、新建DateTimeDialog2.1 创建静态方法2.1.1 创建SetDateDialog&#xff0c;用于选择日期2.1.2 SetDateDialog中绑定textVi…

Web前端-时间日期控件

需求&#xff1a;同时可以选择 时间 和 日期 通过设置type属性为datetime&#xff0c;即可在同一个选择器里同时进行日期和时间的选择 <template><div class"block"><span class"demonstration">默认</span><el-date-pickerv…

android时间控件

原文地址&#xff1a;http://www.360doc.com/content/14/0617/16/18203124_387517665.shtml 前言 这一篇博客分别讲解Android平台下&#xff0c;关于日期和时间的几个相关控件。包括DatePicker&#xff08;日期选择控件&#xff09;、TimePicker&#xff08;时间选择控件&…

时间控件(选择时间范围的插件)

后台开发&#xff0c;一般都是有筛选条件的查询&#xff0c;那么问题就来了&#xff0c;根据日期范围搜索的情况下&#xff0c;插件要怎么选&#xff1f;&#xff1f;&#xff1f;&#xff1f; 这个是最开始&#xff0c;我采用的是两个时间插件&#xff0c;其他也没啥&#xff…

jQuery时间控件

时间控件 <!DOCTYPE html> <html><head><title></title><meta http-equiv"Content-Type" content"text/html; charsetutf-8" /><style>.dateinputer{line-height:40px;height:40px;margin:10px 0;border:1px s…

日期/时间控件DateTimePicker

概述&#xff1a; DateTimePicker外观像一个组合框&#xff0c;用于显示日期和时间。当单击其下拉箭头时&#xff0c;会出现一个按月份显示的日历&#xff0c;用户可以从中选择日期。 1、时期/时间控件的属性 属性说明Format用于设置显示日期/时间的格式&#xff0c;可选以下值…