去年年底写的一个小游戏
玩法:
- 方向键控制
- 空格随机打乱
- 按下字母a自动还原
介绍:
- 通过递归实现路径搜索
控制台的简单驱动,(在某坐标写入某字符)
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO CursorInfo; //设置控制台用的
void windows_init()
{
GetConsoleCursorInfo(hOut, &CursorInfo); //获取控制台光标信息
CursorInfo.bVisible = false; //隐藏控制台光标
SetConsoleCursorInfo(hOut, &CursorInfo); //设置控制台光标状态
srand(time(0));
}
void set_colo(char colo)//用于设置字体颜色
{
SetConsoleTextAttribute(hOut, colo | hig);
}
void colo_print(char colo, const char* p) // 可以设置颜色的显示
{
SetConsoleTextAttribute(hOut, colo | hig);
printf(p);
SetConsoleTextAttribute(hOut, white | hig);
}
void set_y_x(int y, int x)//设置光标位置
{
COORD pos = { x,y };
SetConsoleCursorPosition(hOut, pos);
}
void y_x_colo_print(int y, int x, char colo, const char* p)//可以设置坐标以及颜色的文件显示
{
set_y_x(y, x);
colo_print(colo, p);
}
char get_key() //获得按键键值
{
char a;
if (_kbhit() == 1) //由于单使用 _getch()会导致程序堵塞,所以用先用_kbhit()获得是否有按键按下
{
a = _getch();
return a;
}
return 0;
}
long HAL_GetTick()
{
return clock();
}
void HAL_Delay(long a)
{
long b;
b = HAL_GetTick() + a;
while (b> HAL_GetTick());
}
主代码
#define fram_color lightblue //边框颜色
#define d_color white //数字颜色
uint8_t num_array[3][3] = { 1,2,3,4,5,6,7,8,0 };
unsigned int step = 0; //步数
unsigned char hh = 0, mm = 0, ss = 0; //时间 时分秒
void dis_map()
{
char y, x,buff[1];
for (y = 0; y < 3; y++)
{
for (x = 0; x < 3; x++)
{
y_x_colo_print(y,x*3,fram_color,"[");
if (num_array[y][x] != 0)
{
sprintf(buff, "%d", num_array[y][x]);
y_x_colo_print(y, (x * 3) + 1, d_color, buff);
}
else
{
y_x_colo_print(y, (x * 3) + 1, d_color, " ");
}
y_x_colo_print(y, (x * 3) + 2, fram_color, "]");
}
}
}
unsigned char zerox; //空白的位置
unsigned char zeroy;
void lookupzero()//找空白的位置
{
char x, y;
for (y = 0; y < 3; y++)
{
for (x = 0; x < 3; x++)
{
if (num_array[y][x] == 0)
{
zerox = x;
zeroy = y;
}
}
}
}
int move(char dir, char t)//移动方向,是否真移动
{
char index;
if (dir == 0)
{
lookupzero();
if (zeroy != 2)
{
if (t == 1)
{
num_array[zeroy][zerox] = num_array[zeroy + 1][zerox];
num_array[zeroy + 1][zerox] = 0;
}
return 1;
}
}
if (dir == 1)
{
lookupzero();
if (zeroy != 0)
{
if (t == 1)
{
num_array[zeroy][zerox] = num_array[zeroy - 1][zerox];
num_array[zeroy - 1][zerox] = 0;
}
return 1;
}
}
if (dir == 2)
{
lookupzero();
if (zerox != 2)
{
if (t == 1)
{
num_array[zeroy][zerox] = num_array[zeroy][zerox + 1];
num_array[zeroy][zerox + 1] = 0;
}
return 1;
}
}
if (dir == 3)
{
lookupzero();
if (zerox != 0)
{
if (t == 1)
{
num_array[zeroy][zerox] = num_array[zeroy][zerox - 1];
num_array[zeroy][zerox - 1] = 0;
}
return 1;
}
}
return 0;
}
void randommove(int i)//随机移动i次
{
int a, b, c;
for (a = 0; a < i; a++)
{
do
{
b = rand() % 4;
c = move(b, 1);
} while (!c);
}
}
int checkwin()//检查胜利
{
if (num_array[0][0] == 1 & num_array[0][1] == 2 & num_array[0][2] == 3 & num_array[1][0] == 4 & num_array[1][1] == 5 & num_array[1][2] == 6 & num_array[2][0] == 7 & num_array[2][1] == 8 & num_array[2][2] == 0)
{
return 1;
}
else
{
return 0;
}
}
void dis_data()
{
char buff[16];
sprintf(buff, "step:%04d\n time:%02d:%02d:%02d", step,hh,mm,ss);
y_x_colo_print(4,0,green,buff);
}
/********************/
//自动还原功能,比赛用不到但可以研究一下
unsigned int astepnum = 0; //移动步骤
unsigned int cacemap[999][3][3]; //缓存地图
void goandback(char a) //0前进记录一步 1后退还原一步
{
char x, y;
if (a == 0)
{
for (y = 0; y < 3; y++)
{
for (x = 0; x < 3; x++)
{
cacemap[astepnum][y][x] = num_array[y][x];
}
}
astepnum += 1;
}
if (a == 1)
{
astepnum -= 1;
for (y = 0; y < 3; y++)
{
for (x = 0; x < 3; x++)
{
num_array[y][x] = cacemap[astepnum - 1][y][x];
}
}
}
}
int constback(char a)//对方向取个反 防止抽搐
{
if (a == 0)
{
return 1;
}
if (a == 1)
{
return 0;
}
if (a == 2)
{
return 3;
}
if (a == 3)
{
return 2;
}
}
int dil(char t) //
{
char a = 0, b, c;
char x, y;
b = 0;
for (a = 0; a < 4; a++)
{
if (a != constback(t) & astepnum <= 25)
{
if (move(a, 1))
{
goandback(0);
if (checkwin())
{
return 1;
}
else
{
if (dil(a)) { return 1; }
}
}
}
}
goandback(1);
return 0;
}
char autorun()
{
char a;
char x, y;
goandback(0);
if (dil(0))
{
for (a = 0; a < astepnum; a++)
{
for (y = 0; y < 3; y++)
{
for (x = 0; x < 3; x++)
{
num_array[y][x] = cacemap[a][y][x];
}
}
dis_map();
step += 1;
HAL_Delay(400);
}
return 1;
}
else
{
return 0;
}
}
/*******************/
void game_info()
{
printf("华容道小游戏\n吴文峰\n2019-12-04\n按任意键开始");
_getch();
}
int main()
{
enum {star,playing,automove,over};
char run = star,key;
long second_t=0; //时间变量
//game_info();
windows_init();
while (1)
{
key= get_key(); //获得按键键值
switch (run)
{
case star:
randommove(500);//随机移动n次
step = 0;
hh = 0; mm = 0; ss = 0;
astepnum = 0;
y_x_colo_print(6, 0, green, " ");
run = playing;
break;
case playing:
if (HAL_GetTick() > second_t)
{
second_t += 1000;
ss++;
if (ss == 60) { ss = 0; mm++; if (mm == 60) { mm = 0; hh++; } }
}
if (key == space) { run = star; }
if (key == dd) { move(1, 1); step++;}
if (key == ll) { move(2, 1); step++;}
if (key == uu) { move(0, 1); step++;}
if (key == rr) { move(3, 1); step++;}
if (key == 97) { run = automove; }//
if (checkwin())
{
y_x_colo_print(6, 0, green, "you win!");
run = over;
}
dis_data();
break;
case over:
if (key == space) { run = star; }
break;
case automove:
if (autorun())
{
}
else
{
y_x_colo_print(6, 0, green, "no");
}
run = playing;
break;
default:
break;
}
dis_map();
y_x_colo_print(8, 0, red, "华容道小游戏\n吴文峰\n2019-12-04\n\n方向键移动\n空格随机打乱\n按字母a自动还原");
}
}
2 条评论
请问这是vs下编译运行的吗
是的