#include <stdio.h>
#include <Windows.h>
#include <time.h>
#include <conio.h>
#include <stdlib.h>
#pragma comment(lib, "Winmm.lib")
#define hang 25
#define lie 30
int map[hang+1][lie+1];
int judge[hang+1];
int flag = 1,speed=400, choose = 1,next_choose=1,score=0;
//出现一个方块的位置
struct {
int x;
int y;
}m[4];
//下一个方块的形状
struct {
int x;
int y;
}next[4];
int wherex();
int wherey();
void gotoxy(int x,int y);
void init();
void graph();
void console();
void down();
int stop();
void remove();
void change();
int main()
{
//界面输出
init();
//添加背景音乐
//PlaySound(TEXT("The Truth That You Leave.wav"), NULL, SND_FILENAME | SND_ASYNC | SND_LOOP);
//初始化地图
for (int i = 0; i <= hang; ++i)
{
judge[i] = 0;
for (int j = 0; j <= lie; ++j)
{
map[i][j] = 0;
}
}
//调用第一个随机选择图形函数
graph();
//俄罗斯方块开始
while (flag == 1)
{
for (int i = 0; i < 4; i++)
{
m[i].x = next[i].x;
m[i].y = next[i].y;
}
choose = next_choose;
down();
}
//俄罗斯方块结束
system("cls");
printf("gameover!");
system("pause");
return 0;
}
int wherex()
{
CONSOLE_SCREEN_BUFFER_INFO pBuffer;
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &pBuffer);
return (pBuffer.dwCursorPosition.X + 1);
}
int wherey()
{
CONSOLE_SCREEN_BUFFER_INFO pBuffer;
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &pBuffer);
return (pBuffer.dwCursorPosition.Y + 1);
}
//移动光标函数
void gotoxy(int x, int y)//控制光标位置
{
COORD c;
c.X = x - 1;
c.Y = y - 1;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);
}
//初始化地图函数
void init()
{
for (int i = 1; i <= hang; ++i)//输出两列
{
gotoxy(1,i);
printf("*");
gotoxy(lie,i);
printf("*");
}
for (int i = 1; i <= lie; ++i)//输出两行
{
gotoxy(i,1);
printf("*");
gotoxy(i,hang);
printf("*");
}
gotoxy(lie + lie / 2, 2);
printf("下一个图形");
for (int i = 3; i < 9; i++)
{
gotoxy(lie + lie / 2, i);
printf("*");
gotoxy(lie + lie / 2 + 10, i);
printf("*");
}
for (int i = lie + lie / 2; i < lie + lie / 2 + 11; i++)
{
gotoxy(i, 3);
printf("*");
gotoxy(i, 9);
printf("*");
}
gotoxy(lie + lie / 2, hang);
printf("你的得分是:");
return;
}
//生成随机图形
void graph()
{
//初始化图形坐标,准备下落
next[0].x = lie / 2 - 1;
next[0].y = 2;
srand((unsigned)time(NULL));
next_choose = rand() % 7 + 1;
switch (next_choose)
{
case 1:
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 1);
for (int i = 1; i < 4; i++)
{
next[i].x = next[i - 1].x;
next[i].y = next[i - 1].y - 1;
}
break;
case 2:
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 2);
next[1].x = next[0].x;
next[1].y = next[0].y - 1;
for (int i = 2; i < 4; i++)
{
next[i].x = next[i - 1].x+2;
next[i].y = next[i - 1].y;
}
break;
case 3:
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 3);
next[1].x = next[0].x;
next[1].y = next[0].y-1;
for (int i = 2; i < 4; i++)
{
next[i].x = next[i - 1].x - 2;
next[i].y = next[i - 1].y;
}
break;
case 4:
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 4);
next[1].x = next[0].x;
next[1].y = next[0].y - 1;
next[2].x = next[1].x-2;
next[2].y = next[1].y;
next[3].x = next[1].x+2;
next[3].y = next[1].y;
break;
case 5:
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 5);
next[1].x = next[0].x;
next[1].y = next[0].y - 1;
next[2].x = next[0].x + 2;
next[2].y = next[0].y;
next[3].x = next[2].x;
next[3].y = next[2].y - 1;
break;
case 6:
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 6);
next[1].x = next[0].x + 2;
next[1].y = next[0].y;
next[2].x = next[0].x;
next[2].y = next[0].y - 1;
next[3].x = next[2].x - 2;
next[3].y = next[2].y;
break;
case 7:
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 8);
next[1].x = next[0].x + 2;
next[1].y = next[0].y;
next[2].x = next[1].x;
next[2].y = next[1].y - 1;
next[3].x = next[2].x + 2;
next[3].y = next[2].y;
break;
}
}
int stop()
{
int t=1;
//判断一个图形的四个小方块是否到了边境或碰到其他方块
for (int i = 0; i < 4; ++i)
{
if (m[i].y == hang || map[m[i].y][m[i].x] == 1)
{
t = 0;
break;
}
}
return t;
}
void down()
{
for (int i = 0; i < 4; i++)
{
gotoxy(next[i].x + lie + 5, next[i].y + 5);
printf(" ");
}
//生成下一个将出现的图形
graph();
for (int i = 0; i < 4; i++)
{
gotoxy(next[i].x+lie+5, next[i].y+5);
printf("□");
}
//一个图形下移直到条件满足停止
for (int f = 1;stop();++f)
{
Sleep(speed);
if (f > 1)
{
//消去上一次输出的图形
for (int i = 0; i < 4; i++)
{
gotoxy(m[i].x, m[i].y-1);
printf(" ");
}
}
//判断是否键盘有输入
while (_kbhit() != 0)
{
//调用控制函数
console();
}
//输出这一次的图形
for (int i = 0; i < 4; i++)
{
gotoxy(m[i].x, m[i].y);
if(m[i].x>1&&m[i].y>1)
printf("□");
}
//判断是否停止
if (stop)
{
//每个方块下移一位
for (int i = 0; i < 4; i++)
{
++m[i].y;
}
}
}
//一个图形停止后判断速度是否需要初始化
if (speed == 0)
{
speed = 300;
}
//调用记录图像位置和决定是否消除的函数
remove();
//判断游戏是否结束
for (int i = 0; i < 4; ++i)
{
if (m[i].y <= 2)
flag = 0;
}
}
void console()
{
int i,c,temp=1;
//判断输入是否为空格
switch (_getch())
{
case 32:
speed = 0;
return;
}
//第二次接收方向键
c = _getch();
switch (c)
{
case 72:
for (i = 0; i < 4; i++)
{
if (map[m[i].y][m[i].x + 2] == 1 )
if( map[m[i].y][m[i].x - 2] == 1)
if(map[m[i].y - 1][m[i].x] == 1)
if(map[m[i].y - 1][m[i].x-2] == 1)
if(map[m[i].y - 1][m[i].x+2] == 1)
temp = 0;
}
if(temp==1)
change();
break;
case 75:
for (i = 0; i < 4; i++)//判断是否可以左移
{
if (m[i].x - 2 <= 1||map[m[i].y][m[i].x-2]==1)
{
temp = 0;
break;
}
}
if (temp == 1)
{
for (i = 0; i < 4; i++)
{
m[i].x -= 2;
}
}
break;
case 77:
for (i = 0; i < 4; i++)//判断是否可以右移
{
if (m[i].x + 2 > lie-1 || map[m[i].y][m[i].x + 2] == 1)
{
temp = 0;
}
}
if(temp==1)
for (i = 0; i < 4; i++)
m[i].x += 2;
break;
case 80:
for (i = 0; i < 4; i++)//判断是否可以下移
{
if (m[i].y + 1 >= hang || map[m[i].y+1][m[i].x] == 1)
temp = 0;
}
if (temp == 1)
{
for (i = 0; i < 4; i++)
{
m[i].y++;
}
}
break;
}
return;
}
//记录个数与消去函数
void remove()
{
int temp=0;
//记录每一行的方块数
for (int i = 0; i < 4; ++i)
{
map[m[i].y-1][m[i].x] = 1;
judge[m[i].y-1] += 2;
}
//判断是否可以消去
for (int i = 1; i < hang; i++)
{
if (judge[i] >= lie - 2)
{
temp = 1;
for (int t = i; t > 2; t--)
{
for (int j = 2; j < lie; j+=2)
{
map[t][j] = map[t - 1][j];
}
judge[t] = judge[t - 1];
}
//计分并输出
score += 10;
gotoxy(lie + lie / 2, hang+1);
printf("%d", score);
}
}
//覆盖成现有图形
if (temp == 1)
{
for (int i = hang-1; i > 1; --i)
{
for (int j = 2; j < lie; j+=2)
{
if (map[i][j] == 1)
{
gotoxy(j, i);
printf("□");
}
else {
gotoxy(j, i);
printf(" ");
}
}
}
}
return;
}
//图形旋转
void change()
{
switch (choose)
{
case 1:
if (m[2].x + 2 < lie && m[2].x - 4 > 1)
{
if (m[2].y - m[1].y < 0) {
m[0].x = m[2].x-4;
m[0].y = m[2].y;
m[1].x = m[2].x-2;
m[1].y = m[2].y;
m[3].x = m[2].x+2;
m[3].y = m[2].y;
}
else {
m[0].x = m[2].x;
m[0].y = m[2].y+2;
m[1].x = m[2].x;
m[1].y = m[2].y+1;
m[3].x = m[2].x;
m[3].y = m[2].y-1;
}
}
break;
case 2:
if (m[2].x + 2 < lie && m[2].x - 2 > 1)
{
if (m[2].x - m[1].x > 0)
{
m[1].x = m[2].x;
m[1].y = m[2].y - 1;
m[0].x = m[1].x - 2;
m[0].y = m[1].y;
m[3].x = m[2].x;
m[3].y = m[2].y + 1;
}
else if (m[2].y - m[1].y > 0)
{
m[1].x = m[2].x + 2;
m[1].y = m[2].y;
m[0].x = m[1].x;
m[0].y = m[1].y - 1;
m[3].x = m[2].x - 2;
m[3].y = m[2].y;
}
else if (m[2].x - m[1].x < 0)
{
m[1].x = m[2].x;
m[1].y = m[2].y+1;
m[0].x = m[1].x + 2;
m[0].y = m[1].y;
m[3].x = m[2].x;
m[3].y = m[2].y - 1;
}
else {
m[1].x = m[2].x - 2;
m[1].y = m[2].y;
m[0].x = m[1].x;
m[0].y = m[1].y + 1;
m[3].x = m[2].x + 2;
m[3].y = m[2].y;
}
}
break;
case 3:
if (m[2].x + 2 < lie && m[2].x - 2 > 1)
{
if (m[2].x - m[1].x < 0)
{
m[0].x -= 4;
m[1].x -= 2;
m[1].y += 1;
m[3].x += 2;
m[3].y -= 1;
}
else if (m[2].y - m[1].y < 0)
{
m[0].y -= 2;
m[1].x -= 2;
m[1].y -= 1;
m[3].x += 2;
m[3].y += 1;
}
else if (m[2].x - m[1].x > 0)
{
m[0].x += 4;
m[1].x += 2;
m[1].y -= 1;
m[3].x -= 2;
m[3].y += 1;
}
else {
m[0].y += 2;
m[1].x += 2;
m[1].y += 1;
m[3].x -= 2;
m[3].y -= 1;
}
}
break;
case 4:
if (m[1].x - 2 > 1 && m[1].x + 2 < lie)
{
if (m[1].y - m[0].y < 0)
{
m[3] = m[0];
m[0] = m[2];
m[2].x += 2;
m[2].y -= 1;
}
else if (m[1].x - m[0].x > 0)
{
m[3] = m[0];
m[0] = m[2];
m[2].x += 2;
m[2].y += 1;
}
else if (m[1].y - m[0].y > 0)
{
m[3] = m[0];
m[0] = m[2];
m[2].x -= 2;
m[2].y += 1;
}
else {
m[3] = m[0];
m[0] = m[2];
m[2].x -= 2;
m[2].y -= 1;
}
}
break;
case 5:
break;
case 6:
if (m[0].x - 2 > 1 && m[0].x + 2 < lie)
{
if (m[0].x - m[1].x < 0)
{
m[2] = m[1];
m[3].x = m[2].x;
m[3].y = m[2].y - 1;
m[1].x = m[0].x;
m[1].y = m[0].y + 1;
}
else if (m[0].y - m[1].y < 0)
{
m[2] = m[1];
m[3].x = m[2].x + 2;
m[3].y = m[2].y;
m[1].x = m[0].x - 2;
m[1].y = m[0].y;
}
else if (m[0].x - m[1].x > 0)
{
m[2] = m[1];
m[3].x = m[2].x;
m[3].y = m[2].y + 1;
m[1].x = m[0].x;
m[1].y = m[0].y-1;
}
else {
m[2] = m[1];
m[3].x = m[2].x - 2;
m[3].y = m[2].y;
m[1].x = m[0].x + 2;
m[1].y = m[0].y;
}
}
break;
case 7:
if (m[1].x - 2 > 1 && m[1].x + 2 < lie)
{
if (m[1].x - m[0].x > 0)
{
m[0] = m[2];
m[2].x = m[1].x + 2;
m[2].y = m[1].y;
m[3].x = m[2].x;
m[3].y = m[2].y + 1;
}
else if (m[1].y - m[0].y > 0)
{
m[0] = m[2];
m[2].x = m[1].x;
m[2].y = m[1].y + 1;
m[3].x = m[2].x - 2;
m[3].y = m[2].y;
}
else if (m[1].x - m[0].x < 0)
{
m[0] = m[2];
m[2].x = m[1].x - 2;
m[2].y = m[1].y;
m[3].x = m[2].x;
m[3].y = m[2].y - 1;
}
else {
m[0] = m[2];
m[2].x = m[1].x;
m[2].y = m[1].y - 1;
m[3].x = m[2].x + 2;
m[3].y = m[2].y;
}
}
break;
}
return;
}