/*************************************
项目名称:俄罗斯方块
编译环境:VS2015 && easyX
建立时间:2017-2-12
创建人: PorYoung
最近修改: 2017-2-13
遗留问题: ① 变形 ②消除 ③计分计时 ④界面美化
最近修改: 2017-2-14
想法:设计横版玩法——左右堆叠,下落至地则失败
遗留问题: ①优化变形方法 ②优化算法,使运行更流畅 ③速度越来越慢 ④部分方块存在bug
16:52 修改: 修改代码,优化速度越来越慢问题
问题: 下落中的方块闪动过快
思考: 如何实现智能play ------ 自我学习功能(记忆操作步骤)
19:00 修改: ①下落方块闪动 ②增加提示下一个方块
问题: 运行过程存在未知bug,导致方块混乱停止下落或者异常退出
遗留: ①优化变形方法 ②计分计时 ③界面美化
**************************************/
#include "resource.h"
#include "graphics.h"
#include "conio.h"
#include "stdlib.h"
#include "time.h"
struct PART
{
//形状1
char part1[4][4] =
{
{0, 1, 1, 0},
{0, 1, 1, 0},
{0, 0, 0, 0},
{0, 0, 0, 0}
};
//形状2
char part2[4][4] =
{
{ 0, 1, 1, 0 },
{ 0, 0, 1, 1 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 }
};
char part3[4][4] =
{
{0, 0, 1, 0},
{0, 1, 1, 0},
{0, 1, 0, 0},
{0, 0, 0, 0}
};
//形状3
char part4[4][4] =
{
{0, 0, 1, 1},
{0, 1, 1, 0},
{0, 0, 0, 0},
{0, 0, 0, 0}
};
char part5[4][4] =
{
{ 0, 1, 0, 0 },
{ 0, 1, 1, 0 },
{ 0, 0, 1, 0 },
{ 0, 0, 0, 0}
};
//形状4
char part6[4][4] =
{
{ 0, 1, 1, 0 },
{ 0, 0, 1, 0 },
{ 0, 0, 1, 0 },
{ 0, 0, 0, 0 }
};
char part7[4][4] =
{
{0, 0, 1, 0},
{1, 1, 1, 0},
{0,},
{0,}
};
char part8[4][4] =
{
{ 0, 1, 0 ,0},
{ 0, 1, 0 ,0},
{ 0, 1, 1 ,0},
{ 0, 0, 0 ,0},
};
char part9[4][4] =
{
{1, 1, 1, 0},
{1, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0}
};
//形状5
char part10[4][4] =
{
{0, 1, 1, 0},
{0, 1, 0, 0},
{0, 1, 0, 0},
{0, 0, 0, 0}
};
char part11[4][4] =
{
{1, 1, 1, 0},
{0, 0, 1, 0},
{0,},
{0,}
};
char part12[4][4] =
{
{0, 0, 1, 0},
{0, 0, 1, 0},
{0, 1, 1, 0},
{0, 0, 0, 0}
};
char part13[4][4] =
{
{1, 0, 0, 0},
{1, 1, 1, 0},
{0,},
{0,}
};
//形状6
char part14[4][4] =
{
{ 0, 1, 0, 0},
{ 0, 1, 0, 0},
{ 0, 1, 0, 0},
{ 0, 1, 0, 0}
};
char part15[4][4] =
{
{1, 1, 1, 1},
{0,},
{0,},
{0,}
};
}part;
int temp = 1; //方块是否停止 0 运动 1 停止
char Map[24][10];
int dir = 0; // 0 不操作 1左 2右 3下 4上
int gameCore = 0; //游戏分数
wchar_t grade[2];
int ch; // 区别方块形状
int chflag = 1;
int chtemp1;
int chtemp2; //两次方块形状
int flag = 0; //速度 0: 慢速(1000ms) 1: 加速 (200ms) 2: 正常(700ms) 3: 加速(100ms) 4:快速(200ms) 5:加速(50ms)
int velocity = 1; //8 :暂停
int tempvel = 0; // 8 暂停
HANDLE hThread;
struct COOR
{
int CRow[4] = { 0 };
int CCol[4] = { 0 };
int n = 0;
}coor;
void initgame();
void randShow();
void draw();
void move();
void Changemove();
void NumCount();
DWORD WINAPI Thread(LPVOID lpParameter);
void initgame()
{
//行宽10*30, 列高20*30
//initgraph(640, 600);
graphdefaults();
cleardevice();
setfillcolor(RGB(86, 86, 86));
solidrectangle(0, 0, 170, 600);
solidrectangle(470, 0, 640, 600);
int row = 0, col = 0;
for (row = 0; row < 24; row++)
{
for (col = 0; col < 10; col++)
{
Map[row][col] = 0;
}
}
dir = 0;
//左边状态栏
setbkmode(TRANSPARENT);
setbkcolor(RGB(68, 68, 68));
settextcolor(RGB(255, 130, 40));
settextstyle(30, 0, L"华文彩云");
clearrectangle(30, 50, 150, 340);
outtextxy(50, 60, L" 变形");
outtextxy(50, 95, L" 加速");
outtextxy(50, 130, L" 左移");
outtextxy(50, 165, L" 右移");
outtextxy(50, 200, L"W 提速");
outtextxy(50, 235, L"S 降速");
outtextxy(28, 270, L"空格 暂停");
outtextxy(28, 305, L"回车 重玩");
settextstyle(20, 8, L"华文彩云");
outtextxy(10, 350, L"Made By PorYoung");
outtextxy(45, 385, L"2017-2-13");
char str2[2];
InputBox(grade, 2, L"游戏难度\n(0->5 由慢到快)", L"选项", 0, 30, 30, true);
WideCharToMultiByte(0, 0, grade, 1, str2, 1, 0, 0);
velocity = atoi(str2);
gameCore = 0;
hThread = CreateThread(NULL, 0, Thread, NULL, 0, NULL);
//第一个随机方块
srand((unsigned int)time(NULL));
chtemp1 = rand() % 14 + 1;
}
void randShow()
{
void initShow(char nowshow[4][4]);
if (chflag == 0)
{
chtemp1 = rand() % 14 + 1;
ch = chtemp2;
chflag = 1;
}
else
{
chtemp2 = rand() % 14 + 1;
ch = chtemp1;
chflag = 0;
}
switch(ch)
{
case 1:
initShow(part.part1);
break;
case 2:
initShow(part.part2);
break;
case 3:
initShow(part.part3);
break;
case 4:
initShow(part.part4);
break;
case 5:
initShow(part.part5);
break;
case 6:
initShow(part.part6);
break;
case 7:
initShow(part.part7);
break;
case 8:
initShow(part.part8);
break;
case 9:
initShow(part.part9);
break;
case 10:
initShow(part.part10);
break;
case 11:
initShow(part.part11);
break;
case 12:
initShow(part.part12);
break;
case 13:
initShow(part.part13);
break;
case 14:
initShow(part.part14);
break;
case 15:
initShow(part.part15);
break;
}
temp = 0;
}
void initShow(char nowshow[4][4])
{
int row = 0, col = 0;
for (row = 0; row < 4; row++)
{
for (col = 0; col < 4; col++)
{
Map[row][col + 4] = nowshow[row][col];
}
}
}
void draw()
{
int num = 0;
for (int row = 23; row > 3; row--)
{
for (int col = 0; col < 10; col++)
{
if (Map[row][col] == 2)
{
setfillcolor(GREEN);
fillrectangle(col*30 + 170, row*30 - 120, col*30 + 30 + 170, row*30 - 90);
}
else if (Map[row][col] == 0) num++;
}
if (num == 10) break;
else num = 0;
}
coor.n = 0;
}
void showMessage()
{
void NextShow(char nextshow[4][4]);
wchar_t str[4];
char str2[4];
settextstyle(30, 0, L"华文彩云");
setbkmode(TRANSPARENT);
setbkcolor(RGB(68, 68, 68));
clearrectangle(500, 200, 620, 340);
itoa(gameCore, str2, 4);
MultiByteToWideChar(0, 0, str2, 4, str, 4);
outtextxy(510, 200, L"SCORE:");
outtextxy(550, 235, str);
//itoa(velocity, str2, 2);
//MultiByteToWideChar(0, 0, str2, 2, str, 2);
outtextxy(510, 270, L"GRADE:");
outtextxy(550, 305, grade);
int chtemp;
if (chflag == 0)
{
chtemp = chtemp2;
}
else chtemp = chtemp1;
switch (chtemp)
{
case 1:
NextShow(part.part1);
break;
case 2:
NextShow(part.part2);
break;
case 3:
NextShow(part.part3);
break;
case 4:
NextShow(part.part4);
break;
case 5:
NextShow(part.part5);
break;
case 6:
NextShow(part.part6);
break;
case 7:
NextShow(part.part7);
break;
case 8:
NextShow(part.part8);
break;
case 9:
NextShow(part.part9);
break;
case 10:
NextShow(part.part10);
break;
case 11:
NextShow(part.part11);
break;
case 12:
NextShow(part.part12);
break;
case 13:
NextShow(part.part13);
break;
case 14:
NextShow(part.part14);
break;
case 15:
NextShow(part.part15);
break;
}
}
void move()
{
void unmove();
switch (ch)
{
case 1:
//能移动
if (Map[coor.CRow[2] + 1][coor.CCol[2]] == 0 && Map[coor.CRow[3] + 1][coor.CCol[3]] == 0 && coor.CRow[3] < 23)
{
Map[coor.CRow[0]][coor.CCol[0]] = 0;
Map[coor.CRow[1]][coor.CCol[1]] = 0;
Map[coor.CRow[2] + 1][coor.CCol[2]] = 1;
Map[coor.CRow[3] + 1][coor.CCol[3]] = 1;
}
//不能移动
else unmove();
break;
case 2:
//能移动
if (Map[coor.CRow[0] + 1][coor.CCol[0]] == 0 && Map[coor.CRow[2] + 1][coor.CCol[2]] == 0 && Map[coor.CRow[3] + 1][coor.CCol[3]] == 0 && coor.CRow[3] < 23)
{
Map[coor.CRow[0]][coor.CCol[0]] = 0;
Map[coor.CRow[1]][coor.CCol[1]] = 0;
Map[coor.CRow[3]][coor.CCol[3]] = 0;
Map[coor.CRow[0] + 1][coor.CCol[0]] = 1;
Map[coor.CRow[2] + 1][coor.CCol[2]] = 1;
Map[coor.CRow[3] + 1][coor.CCol[3]] = 1;
}
//不能移动
else unmove();
break;
case 3:
//能移动
if (Map[coor.CRow[3]][coor.CCol[3] + 1] == 0 && Map[coor.CRow[3] + 1][coor.CCol[3]] == 0 && coor.CRow[3] < 23)
{
Map[coor.CRow[0]][coor.CCol[0]] = 0;
Map[coor.CRow[1]][coor.CCol[1]] = 0;
Map[coor.CRow[3]][coor.CCol[3] + 1] = 1;
Map[coor.CRow[3] + 1][coor.CCol[3]] = 1;
}
else unmove();
break;
case 4:
//能移动
if (Map[coor.CRow[3]][coor.CCol[3] + 1] == 0 && Map[coor.CRow[2] + 1][coor.CCol[2]] == 0 && Map[coor.CRow[3] + 1][coor.CCol[3]] == 0 && coor.CRow[3] < 23)
{
Map[coor.CRow[0]][coor.CCol[0]] = 0;
Map[coor.CRow[1]][coor.CCol[1]] = 0;
Map[coor.CRow[2]][coor.CCol[2]] = 0;
Map[coor.CRow[3]][coor.CCol[3] + 1] = 1;
Map[coor.CRow[2] + 1][coor.CCol[2]] = 1;
Map[coor.CRow[3] + 1][coor.CCol[3]] = 1;
}
//不能移动
else unmove();
break;
case 5:
//能移动
if (Map[coor.CRow[3]][coor.CCol[3] - 1] == 0 && Map[coor.CRow[3] + 1][coor.CCol[3]] == 0 && coor.CRow[3] < 23)
{
Map[coor.CRow[0]][coor.CCol[0]] = 0;
Map[coor.CRow[2]][coor.CCol[2]] = 0;
Map[coor.CRow[3]][coor.CCol[3] - 1] = 1;
Map[coor.CRow[3] + 1][coor.CCol[3]] = 1;
}
//不能移动
else unmove();
break;
case 6:
//能移动
if (Map[coor.CRow[3] + 1][coor.CCol[3]] == 0 && Map[coor.CRow[2]][coor.CCol[2] - 1] == 0 && coor.CRow[3] < 23)
{
Map[coor.CRow[0]][coor.CCol[0]] = 0;
Map[coor.CRow[1]][coor.CCol[1]] = 0;
Map[coor.CRow[2]][coor.CCol[2] - 1] = 1;
Map[coor.CRow[3] + 1][coor.CCol[3]] = 1;
}
//不能移动
else unmove();
break;
case 7:
//能移动
if (Map[coor.CRow[1] + 1][coor.CCol[1]] == 0 && Map[coor.CRow[2] + 1][coor.CCol[2]] == 0 && Map[coor.CRow[3] + 1][coor.CCol[3]] == 0 && coor.CRow[3] < 23)
{
Map[coor.CRow[1] + 1][coor.CCol[1]] = 1;
Map[coor.CRow[2] + 1][coor.CCol[2]] = 1;
Map[coor.CRow[3] + 1][coor.CCol[3]] = 1;
Map[coor.CRow[0]][coor.CCol[0]] = 0;
Map[coor.CRow[1]][coor.CCol[1]] = 0;
Map[coor.CRow[2]][coor.CCol[2]] = 0;
}
else unmove();
break;
case 8:
//能
if (Map[coor.CRow[2] + 1][coor.CCol[2]] == 0 && Map[coor.CRow[3] + 1][coor.CCol[3]] == 0 && coor.CRow[3] < 23)
{
Map[coor.CRow[2] + 1][coor.CCol[2]] = 1;
Map[coor.CRow[3] + 1][coor.CCol[3]] = 1;
Map[coor.CRow[0]][coor.CCol[0]] = 0;
Map[coor.CRow[3]][coor.CCol[3]] = 0;
}
else unmove();
break;
case 9:
if (Map[coor.CRow[3]][coor.CCol[3] + 1] == 0 && Map[coor.CRow[2] + 1][coor.CCol[2]] == 0 && Map[coor.CRow[3] + 1][coor.CCol[3]] == 0 && coor.CRow[3] < 23)
{
//与case4判断相同 与case7移动方法相同
Map[coor.CRow[1] + 1][coor.CCol[1]] = 1;
Map[coor.CRow[2] + 1][coor.CCol[2]] = 1;
Map[coor.CRow[3] + 1][coor.CCol[3]] = 1;
Map[coor.CRow[0]][coor.CCol[0]] = 0;
Map[coor.CRow[1]][coor.CCol[1]] = 0;
Map[coor.CRow[2]][coor.CCol[2]] = 0;
}
else unmove();
break;
case 10:
//能移动
if (Map[coor.CRow[3] + 1][coor.CCol[3]] == 0 && Map[coor.CRow[1] + 1][coor.CCol[1]] == 0 && coor.CRow[3] < 23)
{
Map[coor.CRow[0]][coor.CCol[0]] = 0;
Map[coor.CRow[1]][coor.CCol[1]] = 0;
Map[coor.CRow[2]][coor.CCol[2] + 1] = 1;
Map[coor.CRow[3] + 1][coor.CCol[3]] = 1;
}
//不能移动
else unmove();
break;
case 11:
//能移动
if (Map[coor.CRow[1] + 1][coor.CCol[1]] == 0 && Map[coor.CRow[3] + 1][coor.CCol[3]] == 0 && Map[coor.CRow[0] + 1][coor.CCol[0]] == 0 && coor.CRow[3] < 23)
{
Map[coor.CRow[0] + 1][coor.CCol[0]] = 1;
Map[coor.CRow[1] + 1][coor.CCol[1]] = 1;
Map[coor.CRow[3] + 1][coor.CCol[3]] = 1;
Map[coor.CRow[0]][coor.CCol[0]] = 0;
Map[coor.CRow[1]][coor.CCol[1]] = 0;
Map[coor.CRow[2]][coor.CCol[2]] = 0;
}
else unmove();
break;
case 12:
//能
if (Map[coor.CRow[2] + 1][coor.CCol[2]] == 0 && Map[coor.CRow[3] + 1][coor.CCol[3]] == 0 && coor.CRow[3] < 23)
{
Map[coor.CRow[2] + 1][coor.CCol[2]] = 1;
Map[coor.CRow[3] + 1][coor.CCol[3]] = 1;
Map[coor.CRow[0]][coor.CCol[0]] = 0;
Map[coor.CRow[2]][coor.CCol[2]] = 0;
}
else unmove();
break;
case 13:
if (Map[coor.CRow[1] + 1][coor.CCol[1]] == 0 && Map[coor.CRow[2] + 1][coor.CCol[2]] == 0 && Map[coor.CRow[3] + 1][coor.CCol[3]] == 0 && coor.CRow[3] < 23)
{
Map[coor.CRow[1] + 1][coor.CCol[1]] = 1;
Map[coor.CRow[2] + 1][coor.CCol[2]] = 1;
Map[coor.CRow[3] + 1][coor.CCol[3]] = 1;
Map[coor.CRow[0]][coor.CCol[0]] = 0;
Map[coor.CRow[2]][coor.CCol[2]] = 0;
Map[coor.CRow[3]][coor.CCol[3]] = 0;
}
else unmove();
break;
case 14:
if (Map[coor.CRow[3] + 1][coor.CCol[3]] == 0 && coor.CRow[3] < 23)
{
Map[coor.CRow[0]][coor.CCol[0]] = 0;
Map[coor.CRow[3] + 1][coor.CCol[3]] = 1;
}
else unmove();
break;
case 15:
for (int i = 0; i < 4; i++)
{
if (Map[coor.CRow[i] + 1][coor.CCol[i]] == 0)
{
if (coor.CRow[3] < 23)
{
if (i == 3)
{
Map[coor.CRow[0]][coor.CCol[0]] = 0;
Map[coor.CRow[1]][coor.CCol[1]] = 0;
Map[coor.CRow[2]][coor.CCol[2]] = 0;
Map[coor.CRow[3]][coor.CCol[3]] = 0;
Map[coor.CRow[0] + 1][coor.CCol[0]] = 1;
Map[coor.CRow[1] + 1][coor.CCol[1]] = 1;
Map[coor.CRow[2] + 1][coor.CCol[2]] = 1;
Map[coor.CRow[3] + 1][coor.CCol[3]] = 1;
}
continue;
}
}
unmove();
}
break;
}
}