如何保证百分百吃满全屏呢?,假设蛇在一个圆上跑,所有的食物都在圆上刷新,蛇是不会死的,所以,将点阵连成一个圆,当然是个被 叠的失去梦想的圆,且看下图8*8点阵
沿着黄线路径顺时针和蓝色逆时针,是不是一定不会死,食物都在环路上刷新,但是这样的环产生的蛇就像智障一样,食物在它身边它也不吃,非要把环跑完,那该如何是好?顺便说一句,奇*奇的点阵是无法形成一个包含所有点的环路的。比如3*3。总会有一个点不在环路上。
环路组合与拆分
其中R代表right,D代表down,L为left,U为up,每一个点均指明了蛇头在这一个点的下一个该如何移动。这是极小环路
纵向组合拆分:
左边为两个不相干的环路,右边组合成了一个大环。自己假装站在上面跑一跑看看。
横向组合拆分
自己跑一跑感受一下,红到绿,为组合,绿到红为拆分。
在之前概率性贪吃它的基础上,删去了next_point,添加了以下两个数据结构
bool path_board[16][16];//点是否在环路上
short path[16][16];//每个点上的移动方向,存储L,R,D,U
初始化时,蛇长为2,左上角的极小环路为true,然后根据食物所在目的地,组合环路,每走一步,都重新拆分再组合回路。
组合和拆分的实现
void set_path_board(COORD x, bool t) {
path_board[x.X][x.Y] = t;
path_board[x.X+1][x.Y] = t;
path_board[x.X][x.Y+1] = t;
path_board[x.X+1][x.Y+1] = t;
}//一次性将一个环添加或删除时,修改path_board
bool matrix_no_point(COORD x) {
return board[x.X][x.Y] == false &&
board[x.X + 1][x.Y] == false &&
board[x.X][x.Y + 1] == false &&
board[x.X + 1][x.Y + 1] == false;
}//某一极小环路是否存在蛇的身体,不存在的环路要拆除
bool path_board_not_all_true(COORD x) {
return !(path_board[x.X][x.Y] &&path_board[x.X+1][x.Y+1]);
}//两个极小环路相接的环路是否一个在路径里,一个在路径外,这是可添加路径的判断依据
void add_path_matrix(COORD x) {
if (x.X % 2) {
if (path_board_not_all_true(x)) {
path[x.X][x.Y] = R;
path[x.X + 1][x.Y + 1] = L;
set_path_board({ x.X - 1,x.Y }, true);
set_path_board({ x.X + 1,x.Y }, true);
}
}
else {
if (path_board_not_all_true(x)) {
path[x.X + 1][x.Y] = D;
path[x.X][x.Y + 1] = U;
set_path_board({ x.X,x.Y + 1 }, true);
set_path_board({ x.X,x.Y - 1 }, true);
}
}
}//添加路径
void check_if_del(COORD x) {
if (board[x.X][x.Y] == false && board[x.X + 1][x.Y] == false &&
board[x.X + 1][x.Y + 1] == false && board[x.X][x.Y + 1] == false)
{
set_path_board(x, false);
}
}//判断是否为可剪除的环路
void del_path_matrix(COORD x) {
if (x.X % 2) {
path[x.X][x.Y] = D;
path[x.X + 1][x.Y + 1] = U;
check_if_del({ x.X - 1,x.Y });
check_if_del({ x.X + 1,x.Y });
}
else {
path[x.X + 1][x.Y] = L;
path[x.X][x.Y + 1] = R;
check_if_del({ x.X,x.Y-1 });
check_if_del({ x.X,x.Y+1 });
}
}
环路组合-拆分原则,只有由路径上的极小环与路径外的极小环之间可以组合拆分,已经在路径上的两个极小环之间不可再次组合。
路径生成
void form_path() {
COORD head = body.front();
head.X = head.X & 0xfffe;
head.Y = head.Y & 0xfffe;
COORD end = food;
end.X = end.X & 0xfffe;
end.Y = end.Y & 0xfffe;
short dx;
short dy;
if (head.X > end.X)dx = -2;
else dx = 2;
if (head.Y > end.Y)dy = -2;
else dy = 2;
while (head.X != end.X) {
short x = head.X;
head.X += dx;
add_path_matrix({ (x + head.X) / 2, head.Y });
}
//printf("\n");
// _print();
while (head.Y != end.Y) {
short y = head.Y;
head.Y += dy;
add_path_matrix({end.X,(head.Y+y)/2});
}
}
路径删除
void del_path() {
for (short i = 0; i <=14; i += 2) {
for (short j = 1; j < 14; j += 2) {
if (matrix_no_point({ i,j - 1 }) || matrix_no_point({ i,j + 1 })) {
del_path_matrix({ i, j });
}
if (matrix_no_point({ j-1,i}) || matrix_no_point({ j+1,i })) {
del_path_matrix({ j, i });
}
}
}
}
完整源代码
#include <stdio.h>
#include <iostream>
#include <time.h>
#include <windows.h>
#include <stack>
#include <deque>
#define L 0
#define R 1
#define U 2
#define D 3
using namespace std;
void print(COORD p, char c)//在p所在的位置输出CHAR c所指的字符
{
HANDLE Houtput = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(Houtput, p);
printf("%c", c);
}
bool operator==(COORD &A, COORD&B)
{
if (A.X == B.X&&A.Y == B.Y)return true;
return false;
}
bool operator!=(COORD &A, COORD&B) { return !(A == B); }
class snake {
private:
COORD food;//食物位置
deque<COORD>body;
bool board[16][16];
bool path_board[16][16];
short path[16][16] = {
{R,R,R,R,R,R,R,R,R,R,R,R,R,R,R,D},
{U,L,L,L,L,L,L,L,L,L,L,L,L,L,L,D},
{R,R,R,R,R,R,R,R,R,R,R,R,R,D,U,D},
{U,D,L,L,L,L,L,L,L,L,L,L,L,D,U,D},
{U,D,R,R,R,R,R,R,R,R,R,D,U,D,U,D},
{U,D,U,D,L,L,L,L,L,L,L,D,U,D,U,D},
{U,D,U,D,R,R,R,R,R,D,U,D,U,D,U,D},
{U,D,U,D,U,D,L,L,L,D,U,D,U,D,U,D},
{U,D,U,D,U,D,R,R,U,D,U,D,U,D,U,D},
{U,D,U,D,U,D,U,L,L,L,U,D,U,D,U,D},
{U,D,U,D,U,R,R,R,R,R,U,D,U,D,U,D},
{U,D,U,D,U,L,L,L,L,L,L,L,U,D,U,D},
{U,D,U,R,R,R,R,R,R,R,R,R,U,D,U,D},
{U,D,U,L,L,L,L,L,L,L,L,L,L,L,U,D},
{U,R,R,R,R,R,R,R,R,R,R,R,R,R,U,D},
{U,L,L,L,L,L,L,L,L,L,L,L,L,L,L,L},
};
public:
snake() {
init_board(board);
body.push_back({ 1,0 });
body.push_back({ 0,0 });
print(body[0], '*');
print(body[1], '*');
board[0][0] = true;
board[1][0] = true;
init_board(path_board);
init_path();
set_path_board({ 0,0 }, true);
create_food();
}
void init_board(bool tmp[16][16]) {
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++)tmp[i][j] = false;//点阵全初始为false
}
}
bool is_not_all_true(bool tmp[16][16]) {
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) { if (tmp[i][j] == false)return true; }
}return false;
}/*
void _print() {
for (int y = 0; y < 16; y++) {
for (int x = 0; x < 16; x++)
switch (path[x][y]) {
case L:printf("L "); break;
case R:printf("R "); break;
case D:printf("D "); break;
case U:printf("U "); break;
default:break;
}printf("\n");
}
}*/
bool is_valid_point(COORD tmp) { return !((tmp.X & 0xfff0) || (tmp.Y & 0xfff0)); }
void create_food() {
food.X = rand() % 16;
food.Y = rand() % 16;
while (board[food.X][food.Y]) {food.X = rand() % 16;food.Y = rand() % 16;}
print(food, '*');
del_path();
form_path();
}
void set_board_true(COORD &X) { board[X.X][X.Y] = true; }
void set_board_false(COORD &X) { board[X.X][X.Y] = false; }
void move_to(COORD t) {
if (t != food) {
print(body.back(), ' ');
set_board_false(body.back());
body.pop_back();
body.push_front(t); set_board_true(t);
print(t, '*');
}
else {
body.push_front(t); set_board_true(t);
create_food();
}del_path(); form_path();
}
void move() {
COORD tmp_point = body.front();
switch (path[body.front().X][body.front().Y]) {
case L:tmp_point.X--; move_to(tmp_point); break;
case R:tmp_point.X++; move_to(tmp_point); break;
case D:tmp_point.Y++; move_to(tmp_point); break;
case U:tmp_point.Y--; move_to(tmp_point); break;
default:break;
}
Sleep(30);
}
void init_path() {
for (int i = 0; i < 16; i += 2) {
for (int j = 0; j < 16; j += 2) {
path[i][j] = R;
path[i + 1][j + 1] = L;
path[i][j + 1] = U;
path[i + 1][j] = D;
}
}
}
void set_path_board(COORD x, bool t) {
path_board[x.X][x.Y] = t;
path_board[x.X+1][x.Y] = t;
path_board[x.X][x.Y+1] = t;
path_board[x.X+1][x.Y+1] = t;
}
bool matrix_no_point(COORD x) {
return board[x.X][x.Y] == false &&
board[x.X + 1][x.Y] == false &&
board[x.X][x.Y + 1] == false &&
board[x.X + 1][x.Y + 1] == false;
}
bool path_board_not_all_true(COORD x) {
return !(path_board[x.X][x.Y] &&path_board[x.X+1][x.Y+1]);
}
void add_path_matrix(COORD x) {
if (x.X % 2) {
if (path_board_not_all_true(x)) {
path[x.X][x.Y] = R;
path[x.X + 1][x.Y + 1] = L;
set_path_board({ x.X - 1,x.Y }, true);
set_path_board({ x.X + 1,x.Y }, true);
}
}
else {
if (path_board_not_all_true(x)) {
path[x.X + 1][x.Y] = D;
path[x.X][x.Y + 1] = U;
set_path_board({ x.X,x.Y + 1 }, true);
set_path_board({ x.X,x.Y - 1 }, true);
}
}
}
void check_if_del(COORD x) {
if (board[x.X][x.Y] == false && board[x.X + 1][x.Y] == false &&
board[x.X + 1][x.Y + 1] == false && board[x.X][x.Y + 1] == false)
{
set_path_board(x, false);
}
}
void del_path_matrix(COORD x) {
if (x.X % 2) {
path[x.X][x.Y] = D;
path[x.X + 1][x.Y + 1] = U;
check_if_del({ x.X - 1,x.Y });
check_if_del({ x.X + 1,x.Y });
}
else {
path[x.X + 1][x.Y] = L;
path[x.X][x.Y + 1] = R;
check_if_del({ x.X,x.Y-1 });
check_if_del({ x.X,x.Y+1 });
}
}
void del_path() {
for (short i = 0; i <=14; i += 2) {
for (short j = 1; j < 14; j += 2) {
if (matrix_no_point({ i,j - 1 }) || matrix_no_point({ i,j + 1 })) {
del_path_matrix({ i, j });
}
if (matrix_no_point({ j-1,i}) || matrix_no_point({ j+1,i })) {
del_path_matrix({ j, i });
}
}
}
}
void form_path() {
COORD head = body.front();
head.X = head.X & 0xfffe;
head.Y = head.Y & 0xfffe;
COORD end = food;
end.X = end.X & 0xfffe;
end.Y = end.Y & 0xfffe;
short dx;
short dy;
if (head.X > end.X)dx = -2;
else dx = 2;
if (head.Y > end.Y)dy = -2;
else dy = 2;
while (head.X != end.X) {
short x = head.X;
head.X += dx;
add_path_matrix({ (x + head.X) / 2, head.Y });
}
//printf("\n");
// _print();
while (head.Y != end.Y) {
short y = head.Y;
head.Y += dy;
add_path_matrix({end.X,(head.Y+y)/2});
}
}
};
int main()
{
srand(time(NULL));
snake a;
while (true) {
a.move();
}
}