C++桌面贪吃蛇,能通关的都是大神(Windows可编译)
Posted 蒟蒻一枚
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++桌面贪吃蛇,能通关的都是大神(Windows可编译)相关的知识,希望对你有一定的参考价值。
文章目录
运行效果
实现原理
- 首先拿到所有桌面APP的路径。
- 然后将它们都存进结构体,并存入指针数组(前面的指向后面的)。
- 后面直接每次随机生成食物并且每次判断是否KO就行了。
- 感兴趣也可以看看普通的贪吃蛇。
代码实现(详见注释)
#include <bits/stdc++.h>
#include <windows.h>
#include <commctrl.h>
#include <shlobj.h>
#define get GetAsyncKeyState
#define send SendMessageA
#define LVM LVM_SETITEMPOSITION
#define msg MessageBox
// 大小与速度(速度越小越快)
const int S = 100, V = 300;
// 桌面
HWND D;
// 蛇的结构体
typedef struct Snake {
// 位置
int x, y;
// 蛇的第几节
int idx;
// 下一节
struct Snake* nxt;
} node;
// 蛇头
node* head;
node* t;
// 目前食物的位置
POINT food;
// 目前吃了多少食物
int cnt, idx;
// 分辨率
int w, h;
// 共有多少食物
int sum;
// 找路径
char* Get() {
LPITEMIDLIST pidl;
LPMALLOC pShellMalloc;
char s[200];
if (SUCCEEDED(SHGetMalloc(&pShellMalloc))) {
if (SUCCEEDED(SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOP, &pidl))) {
SHGetPathFromIDListA(pidl, s);
pShellMalloc -> Free(pidl);
}
pShellMalloc -> Release();
}
return s;
}
// 初始化
void init() {
srand((unsigned int)time(0));
HWND grand = FindWindowA("Progman", "Program Manager"), fa = FindWindowExA(grand, NULL, "SHELLDLL_DefView", NULL);
D = FindWindowExA(fa, 0, "SysListView32", "FolderView");
sum = send(D, LVM_GETITEMCOUNT, 0, 0);
w = GetSystemMetrics(SM_CXSCREEN);
h = GetSystemMetrics(SM_CYSCREEN);
head = (node*) malloc (sizeof head);
head -> x = rand() % (w / S) * S;
head -> y = rand() % (h / S) * S;
head -> idx = 0;
head -> nxt = NULL;
for (int i = 0; i < sum; ++i) {
send(D, LVM, i, (h << 16) + w);
}
}
// 游戏界面
void Game() {
// 输出蛇头
send(D, LVM, head -> idx, (head -> y << 16) + head -> x);
A:
food.x = rand() % (w / S) * S;
food.y = rand() % (h / S) * S;
// 如果新生成的食物位置和蛇头位置重合就重生成
if (head -> x == food.x && head -> y == food.y) {
goto A;
}
// 输出食物
send(D, LVM, 1, (food.y << 16) + food.x);
// 移动方向,最开始向右
node move;
move.x = 1;
move.y = 0;
// 都吃了就成功了
while (cnt < sum) {
if (get(VK_UP)) {
move.x = 0;
move.y = -1;
}
if (get(VK_DOWN)) {
move.x = 0;
move.y = 1;
}
if (get(VK_LEFT)) {
move.x = -1;
move.y = 0;
}
if (get(VK_RIGHT)) {
move.x = 1;
move.y = 0;
}
if (get(VK_ESCAPE)) {
msg(D, TEXT("再见,下次再来玩呦~"), TEXT(""), MB_OK | MB_ICONEXCLAMATION);
exit(0);
}
if (get(VK_SPACE)) {
while (true) {
Sleep(500);
if (get(VK_SPACE)) {
break;
}
}
}
if (head -> x == food.x && head -> y == food.y) {
++idx;
++cnt;
node* T;
T = (node*) malloc (sizeof(node));
T -> x = food.x;
T -> y = food.y;
T -> idx = idx;
T -> nxt = NULL;
t = head;
while (t -> nxt != NULL) {
t = t -> nxt;
}
t -> nxt = T;
t = head;
t -> x += move.x * S;
t -> y += move.y * S;
while (t != NULL) {
send(D, LVM, t -> idx, (t -> y << 16) + t -> x);
t = t -> nxt;
}
B:
food.x = rand() % (w / S) * S;
food.y = rand() % (h / S) * S;
if (head -> x == food.x && head -> y == food.y) {
goto B;
}
send(D, LVM, idx + 1, (food.y << 16) + food.x);
} else {
node t1, t2;
t = head;
t1.x = t -> x;
t1.y = t -> y;
t -> x += move.x * S;
t -> y += move.y * S;
send(D, LVM, t -> idx, (t -> y << 16) + t -> x);
t = head -> nxt;
while (t != NULL) {
t2.x = t -> x;
t2.y = t -> y;
t -> x = t1.x;
t -> y = t1.y;
send(D, LVM, t -> idx, (t -> y << 16) + t -> x);
t1.x = t2.x;
t1.y = t2.y;
t = t -> nxt;
}
if (head -> x > w || head -> x < 0 || head -> y > h || head -> y < 0) {
msg(D, TEXT("孩纸你撞到墙了,重来吧"), TEXT(""), MB_OK | MB_ICONEXCLAMATION);
exit(0);
}
t = head -> nxt;
while (t != NULL) {
if (t -> x == head -> x && t -> y == head -> y) {
msg(D, TEXT("孩纸你撞到自己了,重来吧"), TEXT(""), MB_OK | MB_ICONEXCLAMATION);
exit(0);
}
t = t -> nxt;
}
}
Sleep(V);
}
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) {
init();
msg(D, TEXT("游戏规则:↑↓←→控制方向,空格暂停,再按一次空格继续,Esc退出。要好好记住哦~"), TEXT(""), MB_OK | MB_ICONEXCLAMATION);
msg(D, TEXT("准备开始游戏..."), TEXT(""), MB_OK | MB_ICONEXCLAMATION);
Game();
return 0;
}
以上是关于C++桌面贪吃蛇,能通关的都是大神(Windows可编译)的主要内容,如果未能解决你的问题,请参考以下文章