拉灯游戏加强版

#include<windows.h>  
#include<conio.h>  
#include<cstdio>  
#include<ctime>  
#include<cstring>  
#include<cstdlib>  
#include<algorithm>
#define N 40  
#define BOARDX(x) ((x)-OFFSETX)/2  
#define BOARDY(y) (y)-OFFSETY  
#define SCREENX(x) (x)*2+OFFSETX  
#define SCREENY(y) (y)+OFFSETY  
#define BACKGROUND_WHITE (BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED)  
#define FOREGROUND_WHITE (FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED)  
using namespace std;
int QT;  
int f[N][N];
int a[N*N][N*N];
int ans[N][N];
int which[N*N],ins[N*N];
int OFFSETX=3;  
int OFFSETY=3;  
int HEIGHT;  
int WIDTH;  
int LAMP;  
int LEVEL;  
HANDLE hIn,hOut;  
const int dir[4][2]={  
    0,1,  
    1,0,  
    0,-1,  
    -1,0  
};

void writeChar(LPCSTR pChar,COORD wrtCrd);  
void newgame();  
void levelmade();  
void gamemade();  
bool is_win();  
void drawCell(int x,int y);  
void write();  
void initgame();  
void doing();  
void WinGame();  
void exchange(int x,int y);  
void clearScreen();  

void AnsMade()
{
    memset(a,0,sizeof(a));
    for(int i=1;i<=HEIGHT;i++)
    {
        for(int j=1;j<=WIDTH;j++)
        {
            int tot=(i-1)*WIDTH+j;
            a[tot][tot]=1;
            for(int k=0;k<4;k++)
            {
                int x=i+dir[k][0],y=j+dir[k][1];
                if(x>HEIGHT||x<=0||y<=0||y>WIDTH)continue;
                a[tot][(x-1)*WIDTH+y]=1;
            }
        }
    }
}

void drawAns(int x,int y)  
{  
    char buf[5]={0};  
    switch (ans[x][y])  
    {  
        case 0:  
            sprintf(buf,"○\0");  
            break;  
        case 1:  
            sprintf(buf,"●\0");  
            break;  
    }  
    COORD cci={SCREENX(x),SCREENY(y)};  
    writeChar(buf,cci);  
}  

void GetAns()
{
    SetConsoleTitle("拉灯游戏提示界面   F2:返回");
    AnsMade();
    for(int i=1;i<=HEIGHT;i++)
        for(int j=1;j<=WIDTH;j++)
            a[(i-1)*WIDTH+j][HEIGHT*WIDTH+1]=f[i][j];
    int Equ=HEIGHT*WIDTH,Var=HEIGHT*WIDTH;
    memset(which,0,sizeof(which));
    memset(ins,0,sizeof(ins));
    int i=1,j=1,k;
    while(i<=Equ&&j<=Var)
    {
        for(k=i;k<=Equ;k++)
            if(a[k][j])break;
        if(a[k][j])
        {
            if(k!=i)
                for(int p=j;p<=Var+1;p++)
                    swap(a[i][p],a[k][p]);
            for(k=i+1;k<=Equ;k++)
            {
                if(!a[k][j])continue;
                for(int p=j;p<=Var+1;p++)
                    a[k][p]^=a[i][p];
            }
            which[i]=j,ins[j]=i;
            i++;
        }
        j++;
    }
    for(k=i;k<=Var;k++)
        a[k][Var+1]=1;
    for(k=i-1;k>=1;k--)
    {
        for(int p=which[k]+1;p<=Var;p++)
            if(a[k][p])a[k][Var+1]^=a[ins[p]][Var+1];
    }
    clearScreen();
    memset(ans,0,sizeof(ans));
    for(int i=1;i<=HEIGHT;i++)
        for(int j=1;j<=WIDTH;j++)
            ans[i][j]=a[(i-1)*WIDTH+j][HEIGHT*WIDTH+1];
    for(int i=1;i<=HEIGHT;i++)
        for(int j=1;j<=WIDTH;j++)
            drawAns(i,j);
}

int read()
{
    static char ch;
    static int D;
    while(!isdigit(ch=getch()));
    for(D=ch-'0';isdigit(ch=getch());)
        D=D*10+ch-'0';
    return D;
}

void fillChar(TCHAR cChar, DWORD len, COORD wrtCrd)  
{  
    DWORD wtn;  
    FillConsoleOutputCharacter(hOut, cChar, len, wrtCrd, &wtn);  
}  

void fillAttr(WORD attr, DWORD len, COORD wrtCrd)  
{  
    DWORD wtn;  
    FillConsoleOutputAttribute(hOut, attr, len, wrtCrd, &wtn);  
}  

void clearScreen()  
{  
    COORD crd = {0, 0};  
    CONSOLE_SCREEN_BUFFER_INFO csbi;  
    GetConsoleScreenBufferInfo(hOut, &csbi);  
    fillChar(' ', csbi.dwSize.X * csbi.dwSize.Y, crd);  
    fillAttr(FOREGROUND_WHITE, csbi.dwSize.X * csbi.dwSize.Y, crd);  
}  

void exchange(int x,int y)  
{  
    f[x][y]^=1;  
    for(int j=0;j<4;j++)  
    {  
        int xx=x+dir[j][0];  
        int yy=y+dir[j][1];  
        f[xx][yy]^=1;  
    }  

}  

void writeChar(LPCSTR pChar,COORD wrtCrd)  
{  
    DWORD wtn;  
    WriteConsoleOutputCharacter(hOut,pChar,strlen(pChar),wrtCrd,&wtn);  
}  

void newgame()  
{  
    SetConsoleTitle("拉灯游戏   F1:提示");  
    clearScreen();  
    char buf[50]={0};  
    sprintf(buf,"按任意键开始游戏\0");  
    COORD cci={30,10};  
    writeChar(buf,cci);  
    getch();  
}  

void levelmade()  
{  
    clearScreen();  
    char buf[50]={0};  
    sprintf(buf," 请选择难度等级\0");  
    int x=30;  
    int y=9;  
    COORD cci1={x,y};  
    writeChar(buf,cci1);  
    sprintf(buf,"简单:1 容易:2 困难:3 自定义:4\0");  
    x=25;  
    y=11;  
    COORD cci2={x,y};  
    writeChar(buf,cci2);  
    char k=getch();  
    LEVEL=k-'0';  
    if(LEVEL>4||LEVEL<1)  
        levelmade();  
}  

void gamemade()  
{  
    srand(time(0));  
    if(LEVEL!=4)
    {
        memset(f,0,sizeof(f));
        LAMP=rand()%LAMP+LAMP;  
        for(int i=1;i<=LAMP;i++)  
        {  
            int x=rand()%HEIGHT+1;  
            int y=rand()%WIDTH+1;  
            exchange(x,y);  
        }
    }
}  

bool is_win()  
{  
    for(int i=1;i<=HEIGHT;i++)  
        for(int j=1;j<=WIDTH;j++)  
            if(f[i][j])  
                return 0;  
    return 1;  
}  

void drawCell(int x,int y)  
{  
    char buf[5]={0};  
    switch (f[x][y])  
    {  
        case 0:  
            sprintf(buf,"○\0");  
            break;  
        case 1:  
            sprintf(buf,"●\0");  
            break;  
    }  
    COORD cci={SCREENX(x),SCREENY(y)};  
    writeChar(buf,cci);  
}  

void write()  
{
    SetConsoleTitle("拉灯游戏   F1:提示");
    clearScreen();  
    for(int i=1;i<=HEIGHT;i++)  
    {  
        for(int j=1;j<=WIDTH;j++)  
        {  
            if(!is_win())  
                drawCell(i,j);  
            else  
                WinGame();  
        }  
    }  
}  

void WinGame()  
{  
    clearScreen();  
    char buf[50]={0};  
    sprintf(buf,"恭喜你,你赢了\0");  
    COORD cci={30,10};  
    writeChar(buf,cci);  
    Sleep(100);  
    getch();  
    initgame();  
}

void make_me()
{
    FILE *fin=fopen("tt.in","r");
    fscanf(fin,"%d%d",&WIDTH,&HEIGHT);
    for(int j=1;j<=WIDTH;j++)
        for(int i=1;i<=HEIGHT;i++)
            fscanf(fin,"%d",&f[i][j]);
}

void initgame()  
{  
    levelmade();  
    if(LEVEL==1)  
    {
        HEIGHT=9,WIDTH=9,LAMP=20;  
        gamemade();
    }else if(LEVEL==2)  
    {
        HEIGHT=16,WIDTH=16,LAMP=50;  
        gamemade();
    }else if(LEVEL==3)
    {
        HEIGHT=30,WIDTH=16,LAMP=100;  
        gamemade();
    }else make_me();
    OFFSETX=(70-HEIGHT*2)/2;
    write();  
}  

void onKeyDown(WORD keycode)
{
    switch(keycode)
    {
        case VK_F1:GetAns();break;
        case VK_F2:write();break;
        default:break;
    }
}

int main()  
{  
    hIn=GetStdHandle(STD_INPUT_HANDLE);  
    hOut=GetStdHandle(STD_OUTPUT_HANDLE);  
    CONSOLE_CURSOR_INFO cci;  
    cci.dwSize=1;  
    cci.bVisible=FALSE;  
    SetConsoleCursorInfo(hOut,&cci);  
    newgame();  
    initgame();  
    for(;;)  
    {  
        DWORD nEvts;  
        GetNumberOfConsoleInputEvents(hIn,&nEvts);  
        if(nEvts>0)  
        {  
            INPUT_RECORD inpRec;  
            ReadConsoleInput(hIn,&inpRec,1,&nEvts);  
            if(inpRec.EventType==MOUSE_EVENT)  
            {  
                int x=BOARDX(inpRec.Event.MouseEvent.dwMousePosition.X);  
                int y=BOARDY(inpRec.Event.MouseEvent.dwMousePosition.Y);  
                if(inpRec.Event.MouseEvent.dwEventFlags==MOUSE_MOVED)  
                    continue;  
                if(inpRec.Event.MouseEvent.dwButtonState==FROM_LEFT_1ST_BUTTON_PRESSED)  
                {  
                    exchange(x,y);  
                    write();  
                }else  
                    continue;  
            }
            if(inpRec.EventType==KEY_EVENT)
                onKeyDown(inpRec.Event.KeyEvent.wVirtualKeyCode);
        }  
        FlushConsoleInputBuffer(hIn);  
        Sleep(50);  
    }  
    return 0;  
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值