哈哈哈,终于完成了俄罗斯方块的大作业!

有一说一,尽管有老师给定好的框架,但后续功能在实现上还是会有一点点困难

在编写函数的时候,蒟蒻的我基本上在每一个功能的实现上都历经了千辛万苦,彻夜难眠

当然,现在的代码也并不是完全的,比较令我迷惑的是获取得分这里,无论如何获取的分数都是有问题的,还需后期进一步的试验

不过我坚信,现有的代码应该是万无一失的,如有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++代码相关推荐

  1. linux下c语言俄罗斯方块,Centos 6.2下的C语言编写俄罗斯方块游戏代码

    俄罗斯方块游戏代码如下:                                                  运行结果请点击:http://blog.chinaunix.net/uid- ...

  2. 小翼java_小翼俄罗斯方块java代码

    [实例简介] 感谢小翼的java学习视频教程,个人感觉讲的非常好. 小翼的俄罗斯方块工程项目代码.自己对着视频教学敲的,有些地方对原作者的代码思路有改动.项目完成90%,还有些许功能没有加入进去.下载 ...

  3. 基于STM32F407的俄罗斯方块游戏代码分析

    这里只给了关键代码进行分析,并非全部代码. 项目概述和测试见文章 基于STM32F407的俄罗斯方块小游戏的设计_钻仰弥坚的博客-CSDN博客 一.方块编码的方式 首先需要知道俄罗斯方块本质上为4个小 ...

  4. java俄罗斯方块七中图形类_shell脚本编写的俄罗斯方块游戏代码

    粘贴以下代码到一个空的Shell脚本文件中,并在Bash 中运行即可! #!/bin/bash # Tetris Game # 10.21.2003 xhchen #APP declaration A ...

  5. 俄罗斯方块java代码_俄罗斯方块源代码

    [c++]代码库#include #include #include #define CELL 20 #define ROWS 25 #define COLS 15 //升级所需分数值 #define ...

  6. c语言之 俄罗斯方块源程序代码

    #include <stdio.h> #include <windows.h> #include <conio.h> #include <time.h> ...

  7. 俄罗斯方块C#代码实现

    文章目录 前言 一.先看看效果 二.核心代码 1.代码结构 2.资源文件 3.定义面板控件 4.方块类定义 5.方块形状定义 6.方块面板展示逻辑 总结 前言 学习C#之初,主要感兴趣的还是WinFo ...

  8. php俄罗斯方块代码,[原创]Matlab做的俄罗斯方块(含代码)

    以下是引用swf_2008在2007-5-17 9:36:53的发言: 能不能在方块移除的几句程序后面加些注释,不大看的懂啊.谢谢 for num = 1: length( LastBlockYDat ...

  9. c语言俄罗斯方块游戏代码

    #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <sys/time.h ...

最新文章

  1. cannot import name 'InteractiveConsole'
  2. python在excel中的应用-python中的excel操作
  3. python 文件和目录操作
  4. 在Fedora 14上安装Sun JDK 6 (转载)
  5. poj 2455 Secret Milking Machine(二分枚举+最大流)
  6. GridFS读文件代码示例
  7. “约见”面试官系列之常见面试题之第一百零一篇之vue-router传参(建议收藏)
  8. 重建索引一般需要多久_游泳小白学游泳,一般需要多久才能学会?猜猜看
  9. Scala 2.8馆藏图书馆是“历史上最长的遗书”吗? [关闭]
  10. python处理二进制文件_使用Python进行二进制文件读写的简单方法(推荐)
  11. mysql 集群操作系统_mysql集群部署
  12. sharepoint 2013 配件控制FileUpload如何检查是否图像的方法
  13. MDM页面UI升级介绍
  14. 疫情影响之下,液晶面板价格上涨的期望或成空
  15. php 识别lrc,自动识别LRC歌词精选.pptx
  16. MarkMan – 马克鳗 IU好伙伴啊
  17. 使用OpenWrt创建子网作为二级路由
  18. USTC English Club Note20211222
  19. 智能温室的优缺点,你都知道哪些?
  20. 432 4.3.2 STOREDRV.Deliver; recipient thread limit exceeded

热门文章

  1. Cisco(思科)远程登录路由器
  2. Direct3D9 教程02
  3. 精品帖—matlab求解存在多个非线性不等式约束的多元约束优化问题方法
  4. 中国电信转战搜索市场成败难测(来源:IT时代周刊)
  5. 计算机视觉岗秋招面经
  6. oracle安装搜狗输入法教程,Unbuntu16.04安装搜狗拼音输入法的图文教程
  7. 【macOS】mac电脑M2芯片安装Homebrew 最简单的方法
  8. 2019猪年活动营销不完全攻略
  9. MySQL查询课程没有被选修过_mysql 查询 (二)
  10. Google三驾马车之Bigtable