写了个小游戏,画面非常简陋,但基本的功能实现了
下面是学习WindowsAPI时参考的文章,虽说几乎没看懂。。。
[https://blog.csdn.net/farmwang/article/details/50603608]
[https://blog.csdn.net/celte/article/details/10243309]
[https://blog.csdn.net/m0_37801033/article/details/71540942]
单独绘制数独边框时:(我对颜色搭配实在没啥心得。。。还凑活吧)
单独绘制数独界面时:
main.cpp:
#include
#include "soduko.h"
using namespace std;
int main()
{
system("title 数独");
system("mode con cols=80 lines=35");
soduko matrixone("sodukosamples");
matrixone.play();
return 0;
}
soduko.h:
#ifndef SODUKO_H_INCLUDED
#define SODUKO_H_INCLUDED
#include
#include
#include
#include
#include
#include
#include
using namespace std;
//程序中的数字如果可能造成歧义,尽可能用变量名代替
const int line_basement=12,col_basement=30,region_intverl=2,conorcolor=7,errcolor=4,norcolor=3;
const int ONC=800,SBC=240;
const int HIGH_BITSIZE=16,WEIGHT_BITSIZE=8;
class soduko
{
public:
soduko(string);
~soduko();
void play();//主体函数
void finderrws(int,int);//寻找错误,并为错误设置状态
void relieverr();//当错误被修正时,解除错误状态
bool finderr(int [9][9],int,int);//判断是否存在错误,因为功能与性质的不同不能和finderrws函数合并,感觉有点别扭
void show(int,int,int);//在当前所在的位置显示
void showsame(int,int,int);//当前不是空格时,显示所有与当前数字相同的数字
void solvanswer(int [9][9]);//计算数独答案
private:
int sodukodata[9][9];
int statepara[9][9][4];//position x , position y , color , if can be changed //
};
#endif // SODUKO_H_INCLUDED
soduko.cpp:
#include "soduko.h"
//problem : cannot use "show_same" to relieve the block with SBC//has been overcome
/***********************************外部函数区(WindowsAPI)***************************************/
HANDLE hout=GetStdHandle(STD_OUTPUT_HANDLE);//获取当前窗口句柄(也就是获取窗口状态)
COORD position;
void hide()//隐藏光标
{
CONSOLE_CURSOR_INFO cursor_info={1,0};
SetConsoleCursorInfo(hout, &cursor_info);
}
void SetCurPos(const int x, const int y)//设置光标位置
{
position.X = x;
position.Y = y;
SetConsoleCursorPosition(hout, position);
}
void SetColor(int colorID)//设置文本颜色
{
SetConsoleTextAttribute(hout, colorID);
}
void SetBackColor()//设置文本背景色
{
SetConsoleTextAttribute(hout,
//BACKGROUND_BLUE |
BACKGROUND_INTENSITY|
BACKGROUND_GREEN |
BACKGROUND_RED );
}
//下面两个函数原谅我现学现卖,另外,它们没有也不应该出现在程序的正常线程中,因为一些问题尚未解决
void music()
{
//播放音乐,需要在链接器中添加"winmm",支持wav格式,其他格式似乎不支持
//如果文件不在工程/项目目录下,添加确切位置
//还有,播放音乐时不能进行其他操作,所以不能加入游戏中(除非有暂停和继续播放音乐的函数。。。)
PlaySound("Baptism.wav",NULL,SND_SYNC);
}
//绘制数独的边框,但是只学得懵懵懂懂,单独列出还行,作为游戏的一部分就惨不忍睹
//另外,需要在链接器中添加"gdi32",因为调用了GDI图形接口
//还有,我在编译这个函数时(单独的项目),发现总是画不出来,还得碰运气。。。
//作为经验之谈,编译出现"undefined reference to ......"之类错误的,都是没有在链接器中添加相应的链接
//最后,这个函数还没有正式移入这个程序中,所以没有优化逻辑和细节,造成数字较多,比较臃肿
void drawframe()
{
HPEN hPen;//定义画笔
HBRUSH hBrush;//定义画刷
HWND wnd=FindWindow(NULL,"数独");//不知道获得当前窗口设备句柄的函数,还好找到了这个,获得窗口名为“数独”的窗口的设备句柄
HDC dc=GetDC(wnd);//这个。。。真不懂,大概是获取什么东西
POINT ipion[]={{256,192}};//起始点,不怎么懂
int posx[]={256,256,272,272,304,304,320,320,352,352,368,368,
240,384,384,240,240,384,384,240,240,384,384,240};
int posy[]={192,336,336,192,192,336,336,192,192,336,336,192,
208,208,224,224,256,256,272,272,304,304,320,320};
int ppx[]={288,288,336,336,240,384,384,246};
int ppy[]={192,336,336,192,240,240,288,288};
//绘制矩形
hPen = (HPEN)(GetStockObject(NULL_PEN));
hPen = CreatePen(PS_SOLID, 5, RGB(128, 128, 128));
SelectObject(dc, hPen);
Rectangle(dc,237,189,388,340);
DeleteObject(hPen);//释放画笔
//连线(细线)//之所以没有用矩形来代替连线,是因为函数绘制的矩形实际上不是由线组成,而是一个面,所以多重矩形并不能组成网格
hPen = CreatePen(PS_SOLID, 3, RGB(128, 128, 128));
SelectObject(dc, hPen);
MoveToEx(dc,ppx[0],ppy[0],ipion);
for(int i=1;i<4;i++)
LineTo(dc,ppx[i],ppy[i]);
MoveToEx(dc,ppx[4],ppy[4],ipion);
for(int i=5;i<8;i++)
LineTo(dc,ppx[i],ppy[i]);
DeleteObject(hPen);
//连线(粗线)
hPen = CreatePen(PS_DOT, 1, RGB(128, 128, 128));
SelectObject(dc, hPen);
hBrush = (HBRUSH)(GetStockObject(BLACK_BRUSH));
SelectObject(dc,hBrush);
MoveToEx(dc,posx[0],posy[0],ipion);
for(int i=1;i<12;i++)
LineTo(dc, posx[i], posy[i]);
MoveToEx(dc,posx[12],posy[12],ipion);
for(int i=13;i<24;i++)
LineTo(dc, posx[i], posy[i]);
DeleteObject(hPen);
}
/************************************************************************************/
soduko::soduko(string textdata)
{
//数独的数据存储在文件中
//格式为:文件中数据与数独的显示相似,数据为整型,用空格分开
//数独未填写空格用0表示,其余依旧为1~9
int a=textdata.size();
string judgeprinciple=textdata.substr(a-4,4);
if(judgeprinciple!=".txt")textdata+=".txt";
ifstream input(textdata);
if(!input)
cout<<"Error! Cannot open the file!"<>sodukodata[i][j];
}
for(int i=0;i<9;i++)
{
for(int j=0;j<9;j++)
{
//设置状态(位置,颜色,是否可变)
statepara[i][j][0]=j*region_intverl+col_basement;//position x
statepara[i][j][1]=i+line_basement;//position y
if(sodukodata[i][j]==0)
{
statepara[i][j][2]=norcolor;//normal color = blue
statepara[i][j][3]=1;//can be changed
}
else
{
statepara[i][j][2]=conorcolor;//normal color = white
statepara[i][j][3]=0;//can not be changed
}
}
}
}
soduko::~soduko(){};
void soduko::play()
{
//calculate answer//采取的计算方法一点也不高明,但胜在简单(按照人的正常思路计算比较复杂)
int answer[9][9];
for(int i=0;i<9;i++)
for(int j=0;j<9;j++)
answer[i][j]=sodukodata[i][j];
solvanswer(answer);
//draw the begin view
//drawframe();
//music();
for(int i=0;i<9;i++)
for(int j=0;j<9;j++)
show(i,j,ONC);
//original position of choose
show(0,0,SBC);
showsame(0,0,SBC);
SetCurPos(statepara[0][0][0],statepara[0][0][1]);
hide();
//main
int active_x=0,active_y=0;
char numget;
while((numget=getch()))
{
showsame(active_x,active_y,ONC);
if(numget>48&&numget<58&&statepara[active_x][active_y][3]!=0)
{
sodukodata[active_x][active_y]=numget-48;
show(active_x,active_y,SBC);
}
else if(numget==8&&statepara[active_x][active_y][3]!=0)
{
sodukodata[active_x][active_y]=0;
show(active_x,active_y,SBC);
}
else
{
show(active_x,active_y,ONC);
switch(numget)
{
case 72:
if(active_x>0)
active_x--;
break;//up//明明是UP为什么是x变化呢?这个问题交给读者了
case 75:
if(active_y>0)
active_y--;
break;//left
case 80:
if(active_x<8)
active_x++;
break;//down
case 77:
if(active_y<8)
active_y++;
break;//right
default:break;
}
}
hide();
showsame(active_x,active_y,SBC);
relieverr();
finderrws(active_x,active_y);
show(active_x,active_y,SBC);
//relocate active position
SetColor(statepara[active_x][active_y][2]);
SetCurPos(statepara[active_x][active_y][0],statepara[active_x][active_y][1]);
//judge win
int win=1;
for(int i=0;i<9;i++)
{
for(int j=0;j<9;j++)
if(sodukodata[i][j]!=answer[i][j])
{
win=0;
break;
}
if(win==0)break;
}
if(win==1)
{
SetCurPos(col_basement,3);
SetColor(conorcolor);
cout<<"congratulation! You win the game!"<