俄罗斯方块C++代码
哈哈哈,终于完成了俄罗斯方块的大作业!
有一说一,尽管有老师给定好的框架,但后续功能在实现上还是会有一点点困难
在编写函数的时候,蒟蒻的我基本上在每一个功能的实现上都历经了千辛万苦,彻夜难眠
当然,现在的代码也并不是完全的,比较令我迷惑的是获取得分这里,无论如何获取的分数都是有问题的,还需后期进一步的试验
不过我坚信,现有的代码应该是万无一失的,如有bug,敬请各位大佬斧正!
(拒绝抄袭!!!)
#include <iostream>
#include <windows.h>
#include <conio.h>
using namespace std;#define SCREEN_WIDTH 16
#define SCREEN_HEIGHT 25
#define BLOCK_SIZE 4//全局变量
int xPos, yPos; //当前方块横、纵坐标
int ground[SCREEN_HEIGHT][SCREEN_WIDTH] = { 0 }; //背景矩阵//声明并初始化俄罗斯方块数组
int blocks[19][4][4] = {{{0, 0, 0, 0}, {1, 1, 1, 1}, {0, 0, 0, 0}, {0, 0, 0, 0}},//0{{0, 0, 1, 0}, {0, 0, 1, 0}, {0, 0, 1, 0}, {0, 0, 1, 0}},//1 l型块{{0, 0, 0, 0}, {0, 1, 1, 0}, {0, 1, 1, 0}, {0, 0, 0, 0}},//2 O型块{{0, 0, 0, 0}, {1, 1, 0, 0}, {0, 1, 1, 0}, {0, 0, 0, 0}},//3{{0, 0, 1, 0}, {0, 1, 1, 0}, {0, 1, 0, 0}, {0, 0, 0, 0}},//4 Z型块{{0, 0, 0, 0}, {0, 0, 1, 1}, {0, 1, 1, 0}, {0, 0, 0, 0}},//5{{0, 1, 0, 0}, {0, 1, 1, 0}, {0, 0, 1, 0}, {0, 0, 0, 0}},//6 S型块{{0, 1, 0, 0}, {0, 1, 0, 0}, {0, 1, 1, 0}, {0, 0, 0, 0}},//7{{0, 0, 0, 0}, {0, 0, 1, 0}, {1, 1, 1, 0}, {0, 0, 0, 0}},//8{{0, 1, 1, 0}, {0, 0, 1, 0}, {0, 0, 1, 0}, {0, 0, 0, 0}},//9{{0, 0, 0, 0}, {0, 1, 1, 1}, {0, 1, 0, 0}, {0, 0, 0, 0}},//10 L型块{{0, 0, 1, 0}, {0, 0, 1, 0}, {0, 1, 1, 0}, {0, 0, 0, 0}},//11{{0, 0, 0, 0}, {1, 1, 1, 0}, {0, 0, 1, 0}, {0, 0, 0, 0}},//12{{0, 1, 1, 0}, {0, 1, 0, 0}, {0, 1, 0, 0}, {0, 0, 0, 0}},//13{{0, 0, 0, 0}, {0, 1, 0, 0}, {0, 1, 1, 1}, {0, 0, 0, 0}},//14 J型块{{0, 0, 0, 0}, {0, 1, 0, 0}, {1, 1, 1, 0}, {0, 0, 0, 0}},//15{{0, 0, 1, 0}, {0, 1, 1, 0}, {0, 0, 1, 0}, {0, 0, 0, 0}},//16{{0, 0, 0, 0}, {1, 1, 1, 0}, {0, 1, 0, 0}, {0, 0, 0, 0}},//17{{0, 1, 0, 0}, {0, 1, 1, 0}, {0, 1, 0, 0}, {0, 0, 0, 0}} };//18 T型块
//在指定位置画一个方块
void drawBlock(int x, int y, int block[][BLOCK_SIZE]);
//把光标定位到指定坐标
void gotoxy(int x, int y);
//清除指定位置的方块
void clearBlock(int x, int y, int block[][BLOCK_SIZE]);
//向下移动方块
bool moveDown(int x, int y, int block[][BLOCK_SIZE]);
//在窗口顶部创建一个新的方块
int createBlock();
//更新背景
void updateGround(int x, int y, int block[][BLOCK_SIZE]);
//向左移动
bool moveLeft(int x, int y, int block[][BLOCK_SIZE]);
//向右移动
bool moveRight(int x, int y, int block[][BLOCK_SIZE]);
//向左旋转
int turnLeft(int x, int y, int block[][BLOCK_SIZE], int num);
//向右旋转
int turnRight(int x, int y, int block[][BLOCK_SIZE], int num);
//翻转180
int reverse(int x, int y, int block[][BLOCK_SIZE], int num);
//消除一行或几行
bool eliminate();int main() {for (int a = 0; a < SCREEN_WIDTH; a++) {//背景ground[SCREEN_HEIGHT - 1][a] = 1;gotoxy(a, SCREEN_HEIGHT - 1);cout << "■";}for (int a = 0; a < SCREEN_HEIGHT; a++) {//背景ground[a][0] = 1;gotoxy(0, a);cout << "■";ground[a][SCREEN_WIDTH - 1] = 1;gotoxy(SCREEN_WIDTH - 1, a);cout << "■";}int xPos = SCREEN_WIDTH / 2 - 2; //初始坐标int yPos = 0;int num;//方块序号while (true) {num = createBlock();if (num == -1) {break;}int xPos = SCREEN_WIDTH / 2 - 2; //初始坐标int yPos = 0;while (true) {eliminate();if (moveDown(xPos, yPos, blocks[num])) {yPos++; //纵坐标加一}else {updateGround(xPos, yPos, blocks[num]);break;}char input;if (_kbhit()) {//获取键盘输入input = _getch();if (input == 'a') {//如果是a,左移if (moveLeft(xPos, yPos, blocks[num])) xPos--;}if (input == 'd') {//如果是d,右移if (moveRight(xPos, yPos, blocks[num])) xPos++;}if (input == 'q') {//如果是q,左旋int n = turnLeft(xPos, yPos, blocks[num], num);if (n != -1) {drawBlock(xPos, yPos, blocks[n]);num = n;}}if (input == 'w') {//如果是w,翻转int n = reverse(xPos, yPos, blocks[num], num);if (n != -1) {drawBlock(xPos, yPos, blocks[n]);num = n;}}if (input == 'e') {//如果是e,右旋int n = turnRight(xPos, yPos, blocks[num], num);if (n != -1) {drawBlock(xPos, yPos, blocks[n]);num = n;}}}Sleep(250); //挂起一秒(1000) 这里觉得一秒有些慢,改为0.25秒}num = 0;}cout << endl << " ";cout << "Game Over!" << endl;return 0;
}
void drawBlock(int x, int y, int block[][BLOCK_SIZE])
{for (int i = 0; i < BLOCK_SIZE; i++) {for (int j = 0; j < BLOCK_SIZE; j++) {if (block[i][j] == 1) {gotoxy(x + j, y + i); //注意横纵坐标的变换cout << "■";}}}
}
void gotoxy(int x, int y)
{COORD point;point.X = x * 2;point.Y = y;SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), point);
}
void clearBlock(int x, int y, int block[][BLOCK_SIZE])
{for (int i = 0; i < BLOCK_SIZE; i++) {for (int j = 0; j < BLOCK_SIZE; j++) {if (block[i][j] == 1) {gotoxy(x + j, y + i); //注意横纵坐标的变换cout << " ";}}}
}
bool moveDown(int x, int y, int block[][BLOCK_SIZE])
{bool canMoveDown = true;for (int i = 0; i < BLOCK_SIZE; i++) { //先判断能否向下移动for (int j = 0; j < BLOCK_SIZE; j++) {if ((block[i][j] > 0)&& ((y + i + 1 == SCREEN_HEIGHT)|| (ground[y + i + 1][x + j] == 1))) {canMoveDown = false;break;}}if (!canMoveDown) break;}if (canMoveDown) {clearBlock(x, y, block); //清除原来位置的方块drawBlock(x, y + 1, block); //在新的位置绘制方块}return canMoveDown;
}
int createBlock()
{int blockIndex = rand() % 19; //随机生成一个新的方块xPos = SCREEN_WIDTH / 2 - 2;yPos = 0;for (int i = 0; i < BLOCK_SIZE; i++) {for (int j = 0; j < BLOCK_SIZE; j++) {if ((blocks[blockIndex][i][j] == 1) //判断能否绘制新方块&& (ground[yPos + i][xPos + j] == 1))return -1;}}drawBlock(xPos, yPos, blocks[blockIndex]); //绘制新方块return blockIndex;
}
void updateGround(int x, int y, int block[][BLOCK_SIZE])
{//把当前方块加入到背景部分for (int i = 0; i < BLOCK_SIZE; i++) {for (int j = 0; j < BLOCK_SIZE; j++) {if (block[i][j] == 1)ground[y + i][x + j] = 1;}}
}
bool eliminate() {bool flag = true;bool n = false;for (int i = SCREEN_HEIGHT - 2; i >= 0; i--) {for (int j = 0; j < SCREEN_WIDTH; j++) {if (ground[i][j] != 1) {//如果背景有一行不全为1就breakflag = false;break;}}if (flag == true) {//有一行要消除n = true;for (int k = 1; k < SCREEN_WIDTH - 1; k++) {gotoxy(k, i);//找到要消除的一行cout << " ";ground[i][k] = 0;}for (int j = i - 1; j >= 0; j--) {for (int k = 1; k < SCREEN_WIDTH - 1; k++) {if (ground[j][k] == 1) {//如果消除的一行上面有方块ground[j][k] = 0;//上行方块清除ground[j + 1][k] = 1;//下行方块出现gotoxy(k, j);cout << " ";gotoxy(k, j + 1);cout << "■";}}}}}return n;
}
bool moveLeft(int x, int y, int block[][BLOCK_SIZE]) {bool canLeft = true;for (int i = 0; i < BLOCK_SIZE; i++) {for (int j = 0; j < BLOCK_SIZE; j++) {if (block[i][j] == 1 && (ground[y + i][x + j - 1] == 1 || x + j - 1 == 0)) {canLeft = false;break;}}if (!canLeft) break;}if (canLeft) {clearBlock(x, y, block);//清除坐标上的图形drawBlock(x - 1, y, block);//左移一格画图}return canLeft;
}
bool moveRight(int x, int y, int block[][BLOCK_SIZE]) {bool canRight = true;for (int i = 0; i < BLOCK_SIZE; i++) {for (int j = 0; j < BLOCK_SIZE; j++) {if (block[i][j] == 1 && (ground[y + i][x + j + 1] == 1) || (x + j + 1 == SCREEN_WIDTH)) {canRight = false;break;}}if (!canRight) break;}if (canRight) {clearBlock(x, y, block);//清除坐标上的图形drawBlock(x + 1, y, block);//右移一格画图}return canRight;
}
int turnLeft(int x, int y, int block[][BLOCK_SIZE], int num) {bool canTurnLeft = true;int n = num;switch (num) {case 0: n = 1; break;case 1: n = 0; break;case 2: n = 2; break;case 3: n = 4; break;case 4: n = 3; break;case 5: n = 6; break;case 6: n = 5; break;case 7: n = 8; break;case 8: n = 9; break;case 9: n = 10; break;case 10: n = 7; break;case 11: n = 12; break;case 12: n = 13; break;case 13: n = 14; break;case 14: n = 11; break;case 15: n = 16; break;case 16: n = 17; break;case 17: n = 18; break;case 18: n = 15; break;}for (int i = 0; i < BLOCK_SIZE; i++) {for (int j = 0; j < BLOCK_SIZE; j++) {if (blocks[n][i][j] == 1 && ground[y + i][x + j] == 1) {canTurnLeft = false;return -1;}}}if (canTurnLeft) {clearBlock(x, y, block);}return n;
}
int turnRight(int x, int y, int block[][BLOCK_SIZE], int num) {bool canTurnRight = true; int n = num;switch (num) {case 0: n = 1; break;case 1: n = 0; break;case 2: n = 2; break;case 3: n = 4; break;case 4: n = 3; break;case 5: n = 6; break;case 6: n = 5; break;case 7: n = 10; break;case 8: n = 7; break;case 9: n = 8; break;case 10: n = 9; break;case 11: n = 14; break;case 12: n = 11; break;case 13: n = 12; break;case 14: n = 13; break;case 15: n = 18; break;case 16: n = 15; break;case 17: n = 16; break;case 18: n = 17; break;}for (int i = 0; i < BLOCK_SIZE; i++) {for (int j = 0; j < BLOCK_SIZE; j++) {if (blocks[n][i][j] == 1 && ground[y + i][x + j] == 1) {canTurnRight = false;return -1;}}}if (canTurnRight) {clearBlock(x, y, block);}return n;
}
int reverse(int x, int y, int block[][BLOCK_SIZE], int num) {bool canReverse = true;int n = num;switch (num) {case 0: n = 0; break;case 1: n = 1; break;case 2: n = 2; break;case 3: n = 5; break;case 4: n = 6; break;case 5: n = 3; break;case 6: n = 4; break;case 7: n = 11; break;case 8: n = 14; break;case 9: n = 13; break;case 10: n = 12; break;case 11: n = 14; break;case 12: n = 10; break;case 13: n = 9; break;case 14: n = 11; break;case 15: n = 17; break;case 16: n = 18; break;case 17: n = 15; break;case 18: n = 16; break;}for (int i = 0; i < BLOCK_SIZE; i++) {for (int j = 0; j < BLOCK_SIZE; j++) {if (blocks[n][i][j] == 1 && ground[y + i][x + j] == 1) {canReverse = false;return -1;}}}if (canReverse) {clearBlock(x, y, block);}return n;
}
俄罗斯方块C++代码相关推荐
- linux下c语言俄罗斯方块,Centos 6.2下的C语言编写俄罗斯方块游戏代码
俄罗斯方块游戏代码如下: 运行结果请点击:http://blog.chinaunix.net/uid- ...
- 小翼java_小翼俄罗斯方块java代码
[实例简介] 感谢小翼的java学习视频教程,个人感觉讲的非常好. 小翼的俄罗斯方块工程项目代码.自己对着视频教学敲的,有些地方对原作者的代码思路有改动.项目完成90%,还有些许功能没有加入进去.下载 ...
- 基于STM32F407的俄罗斯方块游戏代码分析
这里只给了关键代码进行分析,并非全部代码. 项目概述和测试见文章 基于STM32F407的俄罗斯方块小游戏的设计_钻仰弥坚的博客-CSDN博客 一.方块编码的方式 首先需要知道俄罗斯方块本质上为4个小 ...
- java俄罗斯方块七中图形类_shell脚本编写的俄罗斯方块游戏代码
粘贴以下代码到一个空的Shell脚本文件中,并在Bash 中运行即可! #!/bin/bash # Tetris Game # 10.21.2003 xhchen #APP declaration A ...
- 俄罗斯方块java代码_俄罗斯方块源代码
[c++]代码库#include #include #include #define CELL 20 #define ROWS 25 #define COLS 15 //升级所需分数值 #define ...
- c语言之 俄罗斯方块源程序代码
#include <stdio.h> #include <windows.h> #include <conio.h> #include <time.h> ...
- 俄罗斯方块C#代码实现
文章目录 前言 一.先看看效果 二.核心代码 1.代码结构 2.资源文件 3.定义面板控件 4.方块类定义 5.方块形状定义 6.方块面板展示逻辑 总结 前言 学习C#之初,主要感兴趣的还是WinFo ...
- php俄罗斯方块代码,[原创]Matlab做的俄罗斯方块(含代码)
以下是引用swf_2008在2007-5-17 9:36:53的发言: 能不能在方块移除的几句程序后面加些注释,不大看的懂啊.谢谢 for num = 1: length( LastBlockYDat ...
- c语言俄罗斯方块游戏代码
#include <stdio.h> #include <stdlib.h> #include <signal.h> #include <sys/time.h ...
最新文章
- cannot import name 'InteractiveConsole'
- python在excel中的应用-python中的excel操作
- python 文件和目录操作
- 在Fedora 14上安装Sun JDK 6 (转载)
- poj 2455 Secret Milking Machine(二分枚举+最大流)
- GridFS读文件代码示例
- “约见”面试官系列之常见面试题之第一百零一篇之vue-router传参(建议收藏)
- 重建索引一般需要多久_游泳小白学游泳,一般需要多久才能学会?猜猜看
- Scala 2.8馆藏图书馆是“历史上最长的遗书”吗? [关闭]
- python处理二进制文件_使用Python进行二进制文件读写的简单方法(推荐)
- mysql 集群操作系统_mysql集群部署
- sharepoint 2013 配件控制FileUpload如何检查是否图像的方法
- MDM页面UI升级介绍
- 疫情影响之下,液晶面板价格上涨的期望或成空
- php 识别lrc,自动识别LRC歌词精选.pptx
- MarkMan – 马克鳗 IU好伙伴啊
- 使用OpenWrt创建子网作为二级路由
- USTC English Club Note20211222
- 智能温室的优缺点,你都知道哪些?
- 432 4.3.2 STOREDRV.Deliver; recipient thread limit exceeded