上完一学期的课,一直想试下写俄罗斯方块
嗯 下面这个版本的把原先闪屏和延迟改进了 把掉落最后一行不能移动的BUG也改了下
改进的地方是 :
1:下落过程中 以及更新方块的时候,不直接用system("cls")进行清屏
而是用gotoxy 函数将光标移动到需要改变的位置 先擦除 再更新
2:不直接用Sleep(),用时间 和 输入判断 判断是否进行自动下落,
= = 突然想起来 结果发现两个bug 再改改
下面改进版的代码
//ILSSWFR
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<ctime>
#include<conio.h>
#include<string>
#include<cstring>
#include"windows.h"
using namespace std;
void moves(int level,const int *const po,int n,int k,int *flag,int scores,int q,int e,const int *const it);//移动 get
bool ending();//判断是否游戏结束 get
void game_start(int *scores,int *flag,int level);//开始游戏,flag用来记录游戏模式
int rad_pre(int n);//随机下个掉落的方块get
bool judge(int *point,const int *const po,int n);//判断是否可以移动或者下落 get
void print(const int *const po,int n,int arrow);//用来填图已经掉落的方块get
void out(const int *const po,int n,int k,int scores,int q,int e,const int *const it);
int clean(int *score);//用来清除已经可以消去的行以及统计分数 get
void game_start2(int *scores);
int S[27][10] ;//这个是方格的尺寸
const int FK1[4][3][3]={ {{0,0,0},{1,0,0},{1,1,1}}
,{{1,1,0},{1,0,0},{1,0,0}}
,{{0,0,0},{1,1,1},{0,0,1}}
,{{0,1,0},{0,1,0},{1,1,0}}}
, FK2[4][3][3]={{{0,0,0},{0,0,1},{1,1,1}}
,{{1,0,0},{1,0,0},{1,1,0}}
,{{0,0,0},{1,1,1},{1,0,0}}
,{{1,1,0},{0,1,0},{0,1,0}}}
, FK3[2][3][3]={{{0,0,0},{1,1,0},{0,1,1}}
,{{0,1,0},{1,1,0},{1,0,0}}}
, FK4[2][3][3]={{{0,0,0},{0,1,1},{1,1,0}}
,{{1,0,0},{1,1,0},{0,1,0}}}
, FK5[1][2][2]={{{1,1},{1,1}}}
, FK6[4][3][3]={ {{0,0,0},{0,1,0},{1,1,1}}
,{{0,1,0},{1,1,0},{0,1,0}}
,{{0,0,0},{1,1,1},{0,1,0}}
,{{1,0,0},{1,1,0},{1,0,0}}}
, FK7[2][4][4]={{{0,0,0,0},{0,0,0,0},{0,0,0,0},{1,1,1,1}}
,{{1,0,0,0},{1,0,0,0},{1,0,0,0},{1,0,0,0}}};
const int CH[7]={4,4,2,2,1,4,2};//分别是下落图形的样式 和样式的种类
const int *const po[7]={FK1[0][0],FK2[0][0],FK3[0][0],FK4[0][0],FK5[0][0],FK6[0][0],FK7[0][0]};//指针内存储的是内存单元的地址,因为底层const 所以要用*const
const int speed[9]={0,300,250,200,150,100};
int len[7]={3,3,3,3,2,3,4};//方块的边长
int lo_h=4,lo_l=4,h=0,l=4;
int main()
{
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO cci;
GetConsoleCursorInfo(hOut,&cci);
cci.bVisible = FALSE;
SetConsoleCursorInfo(hOut,&cci);
int *start,scores=0,flag=0;
char choose ;
for (;;){
system("cls");
cout<<"--------------------------"<<endl;
cout<<"| |"<<endl;
cout<<"| 欢迎进入游戏界面 |"<<endl;
cout<<"| |"<<endl;
cout<<"--------------------------"<<endl;
cout<<"| |"<<endl;
cout<<"| |"<<endl;
cout<<"| 1:开始游戏 |"<<endl;
cout<<"| 2:操作介绍 |"<<endl;
cout<<"| 3:退出游戏 |"<<endl;
cout<<"| |"<<endl;
cout<<"| |"<<endl;
cout<<"--------------------------"<<endl;
choose=getch();
if (choose=='3')
return 0;
else if (choose=='2'){
system("cls");
cout<<"游戏模式:"<<endl;
cout<<" 1:传统模式 一共有5个关卡以供选择"<<endl;
cout<<" 2:无限模式 每次闯关到达1000分自动进入下一关"<<endl<<endl;
cout<<"分值计算:"<<endl<<" 每成功消去一行获得50分"<<endl;
cout<<" 无法下落时结束游戏"<<endl;
cout<<"具体操作:"<<endl;
cout<<" 向左:A"<<endl;
cout<<" 向右:D"<<endl;
cout<<" 向下:S"<<endl;
cout<<" 变形:W"<<endl<<endl<<endl;
system("pause");
}
else if (choose=='1'){
system("cls");
char cho;
cout<<"请选择模式:"<<endl;
cout<<" 1:传统模式"<<endl;
cout<<" 2:无限模式"<<endl;
cho=getch();
if (cho=='1'){
system("cls");
char level;
cout<<"请选择关卡(1~5):"<<endl;
level=getch();
system("cls");
cout<<" READY GO! "<<endl;
Sleep(500);
scores=0;
game_start(&scores,&flag,level-'0');
}
if (cho=='2'){
system("cls");
cout<<" READY GO! "<<endl;
Sleep(500);
game_start2(&scores);
}
}
}
return 0;
}
int rad_pre(int n)//产生随机值
{
srand((unsigned)time(NULL));
return rand()%n;
}
bool ending()//每次涂抹结束后调用这个函数,判断是否结束游戏
{
for (int i=0;i<4;++i)
for (int j=0;j<10;++j)
if (S[i][j]==1)
return false;
return true;
}
void gotoxy(int x, int y)
{
COORD pos;
pos.X = x;
pos.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}
void print2(int *p,const int *const fk,int k,int color)//处理图形
{
for (int i=0;i<len[k];++i){
for (int j=0;j<len[k];++j){
if (*(fk+i*len[k]+j)){
*(p+i*10+j)=color;
}
}
}
}
void print4(const int *const fk,int k)//处理图形
{ gotoxy(22,0);
for (int i=0;i<len[k];++i){
for (int j=0;j<len[k];++j){
if (*(fk+i*len[k]+j))
cout<<"■";
else cout<<" ";
}
gotoxy(22,i+1);
}
}
bool judge(int *point,const int *const po,int n,int k,int arrow)//point是该指针在S中的位置,剩下的是方块的指针,q是列的位置
{ //n是随机的第几个形态 k是这个第K个方块
int *p=point-10*(len[k]-1);//指向同一
if (arrow==-1){//左为-1 右为1 下为0
const int *const fk = po+n*len[k]*len[k];
print2(p,fk,k,0);
for (int i=0;i<len[k];++i){
for (int j=0;j<len[k];++j)
if (*(fk+i*len[k]+j)&&*(p+i*10-1+j)){
print2(p,fk,k,1);
return false;
}
}
}
if (arrow==1){
const int *const fk = po+n*len[k]*len[k];
print2(p,fk,k,0);
if (lo_l+len[k]>=10){
for (int i=0;i<len[k];++i)
if (*(fk+i*len[k]+len[k]-(lo_l+len[k]-10+1))){
print2(p,fk,k,1);
return false;
}
}
for (int i=0;i<len[k];++i)
for (int j=0;j<len[k];++j)
if (*(fk+i*len[k]+j)&&*(p+i*10+j+1)){
print2(p,fk,k,1); return false;
}
}
if (arrow==0) {
const int *const fk = po+n*len[k]*len[k];
print2(p,fk,k,0);
for (int i=0;i<len[k];++i)
for (int j=0;j<len[k];++j)
if (*(p+(i+1)*10+j)&&*(fk+i*len[k]+j)){
print2(p,fk,k,1); return false;
}
}
if (arrow==3){
if(lo_l+len[k]>10)
return false;
const int *const fuck=po+n*len[k]*len[k];
print2(p,fuck,k,0);
const int *const fk = po+((n+1)%CH[k])*len[k]*len[k];
for(int i=0;i<len[k];++i)
for (int j=0;j<len[k];++j)
if (*(p+i*10+j)&&*(fk+len[k]*i+j)){
print2(p,fuck,k,1); return false;
}
}
return true;
}
int clean(int *score)
{
int flg=0;
for (int i=24;i>=4;--i){
int cnt=0;
for (int j=0;j<10;++j)
if (S[i][j]==1) cnt++;
if (cnt==10){
flg=1;
for (int k=i;k>=1;--k)
for (int j=0;j<10;++j)
S[k][j]=S[k-1][j];
*score+=50;
i+=1;
}
}
return flg;
}
void print(int *point,const int *const po,int n,int k,int arrow)
{
const int *const fk = po+n*len[k]*len[k];
int *p=point-10*(len[k]-1);
p=point-10*(len[k]-1);
if (arrow==-1)
p-=1;
else if (arrow==1)
p+=1;
else if (arrow==3)
p+=10;
for (int i=0;i<len[k];++i){
for (int j=0;j<len[k];++j){
if (!*(p+i*10+j)){
*(p+i*10+j)=*(fk+i*len[k]+j);
}
}
}
}
void out(const int *const po,int n,int k,int scores,int q,int e,const int *const it)
{
system("cls");
const int *const fk = po+n*len[k]*len[k];
const int *const kk = it+e*len[q]*len[q];
for (int i=4;i<24;++i){
for (int j=0;j<10;++j){
if (lo_h-i<len[k]&&i<=lo_h&&j>=lo_l&&j-lo_l<len[k]){
if (*(fk+(len[k]-lo_h+i-1)*len[k]+j-lo_l)||S[i][j])
cout<<"■";
else
cout<<"□";
}
else{
if (S[i][j])
cout<<"■";
else
cout<<"□";
}
}
cout<<"| ";
if (i-4<len[q]&&i>=4)
for (int j=0;j<len[q];++j)
if (*(kk+j+(i-4)*len[q]))
cout<<"■";
else
cout<<" ";
if (i==10)
cout<<"分数:";
if (i==12)
cout<<scores;
if (i==22)
cout<<"1:暂停";
if (i==23)
cout<<"2:退出";
cout<<endl;
}
cout<<"---------------------"<<endl;
}
void print3(int *p,const int *const fk,int k,int color)
{
char fu;
// fu=getch();
string m;
if (color)
m="■";
else
m="□";
int kf=h-len[k],i;
if (kf<=0){
i=-kf-1; kf=0;
}
else {
i=0;kf+=1;
}
gotoxy(lo_l*2,kf);
for (int m=0;i<len[k];++m,++i){
for (int j=0;j<len[k];++j){
if (*(p+i*10+j)&&lo_l+j<10)
cout<<"■";
else if (lo_l+j<10)
cout<<"□";
}
gotoxy(lo_l*2,kf+m+1);
}
//fu=getch();
}
void moves(int level,const int *const poi,int n,int k,int *flag,int scores,int q,int e,const int *const it)//每次开始下落
{
int *p=&S[lo_h][lo_l];
const int *const p_fk = poi;
int kind=n,lens=k;
int flags=0;
char choose;
double star=clock();
for (;;){
if (!flags) choose=0;
// else cout<<choose;
while ((!kbhit()||!(choose=getch()))&&h+5<24){
if (int(clock()-star)<level)
continue ;
else {
star=clock();
}
if (judge(p,p_fk,kind%CH[k],lens,0)){
//
print3(p-10*(len[k]-1),p_fk+(kind%CH[k])*len[k]*len[k],k,0);
print(p,p_fk,kind%CH[k],lens,3);
lo_h+=1;p+=10;h+=1;
print3(p-10*(len[k]-1),p_fk+(kind%CH[k])*len[k]*len[k],k,1);
//system("pause");
// out(p_fk,kind%CH[k],lens,scores,q,e%CH[q],it);
//system("pause");
}
else {
h=0;l=0;lo_h=4;lo_l=4;
return ;
}
}
if (choose=='A'){
// cout<<choose<<endl;
if (lo_l-1>=0){
if (judge(p,p_fk,kind%CH[k],k,-1)){
//指针移动
print3(p-10*(len[k]-1),p_fk+(kind%CH[k])*len[k]*len[k],k,0);
print(p,p_fk,kind%CH[k],lens,-1);
lo_l-=1;p-=1;
print3(p-10*(len[k]-1),p_fk+(kind%CH[k])*len[k]*len[k],k,1);
}
}
}
else if (choose=='W'){
if (judge(p,p_fk,kind%CH[k],lens,3)){
print3(p-10*(len[k]-1),p_fk+(kind%CH[k])*len[k]*len[k],k,0);
kind++;
print(p,p_fk,kind%CH[k],lens,0);
print3(p-10*(len[k]-1),p_fk+(kind%CH[k])*len[k]*len[k],k,1);
}
}
else if (choose=='D'){
if (judge(p,p_fk,kind%CH[k],lens,1)){
print3(p-10*(len[k]-1),p_fk+(kind%CH[k])*len[k]*len[k],k,0);
print(p,p_fk,kind%CH[k],lens,1);
lo_l+=1;p+=1;
print3(p-10*(len[k]-1),p_fk+(kind%CH[k])*len[k]*len[k],k,1);
}
}
else if (choose=='S'){
if(lo_h+1<24){
if (judge(p,p_fk,kind%CH[k],lens,0)){
print3(p-10*(len[k]-1),p_fk+(kind%CH[k])*len[k]*len[k],k,0);
print(p,p_fk,kind%CH[k],lens,3);
lo_h+=1;p+=10;h+=1;
print3(p-10*(len[k]-1),p_fk+(kind%CH[k])*len[k]*len[k],k,1);
}
}
}
else if (choose=='1'){
gotoxy(0,22);
system("pause");
gotoxy(0,22);
for (int i=0;i<20;++i)
cout<<" ";
}
else if (choose=='2'){
*flag=1; return ;
}
if (flags)
choose=0;
if (lo_h>=19) {
if ((!kbhit()||!(choose=getch()))&&(int(clock()-star)>=350)){
lo_h=4;lo_l=4;h=0;
return ;
}
else{
flags=1;
}
}
}
}
void CLEAN()
{
gotoxy(22,0);
for (int i=0;i<4;++i){
for (int j=0;j<4;++j)
cout<<" ";
gotoxy(22,i+1);
}
}
void game_start(int *scores,int *flag,int level)
{
int *p=&S[lo_h][lo_l];
int jud=0,LLL=0;
memset(S,0,sizeof(S));
int q=rad_pre(7),e=rad_pre(CH[q]);
for (;;){
//test
int k=q,n=e;
const int *const kin=po[k];
q=rad_pre(7);
e=rad_pre(CH[q]);
const int *const it=po[q];
if (!LLL){
out(kin,n,k,*scores,q,e%CH[q],it);LLL=1;
}
CLEAN();
print4(it+e*len[q]*len[q],q);
//system("pause");
moves(speed[level],kin,n,k,&jud,*scores,q,e,it);//
if (jud)
break;
if (clean(scores))
out(kin,n,k,*scores,q,e,it);
if (!ending()){
system("cls");
cout<<"您获得的分数是:"<<*scores<<endl;
system("pause");
return ;
}
}
}
void game_start2(int *scores)
{ int *p=&S[lo_h][lo_l];
int jud=0,LLL=0;
memset(S,0,sizeof(S));
int q=rad_pre(7),e=rad_pre(CH[q]);
for (int level=1;level<=5;){
//test
int k=q,n=e;
const int *const kin=po[k];
q=rad_pre(7);
e=rad_pre(CH[q]);
const int *const it=po[q];
if (!LLL){
out(kin,n,k,*scores,q,e%CH[q],it);LLL=1;
}
CLEAN();
print4(it+e*len[q]*len[q],q);
moves(speed[level],kin,n,k,&jud,*scores,q,e,it);//
if (jud)
break;
if (clean(scores))
out(kin,n,k,*scores,q,e,it);
if (*scores>=1000){
level++;
memset(S,0,sizeof(S));
*scores=0;
cout<<" READY GO! "<<endl;
Sleep(500);
continue;
}
if (!ending()){
system("cls");
cout<<"您本关获得的分数是:"<<*scores<<endl;
system("pause");
return ;
}
}
cout<<"您闯过了所有关卡"<<endl;
system("pause");
}