本题要求:
继续昨天的贪吃蛇继续做。
输入格式:
无
输出格式:
无
输入样例:
无
输出样例:
无
解题思路 :
比昨天的加了个randomMove 和 优化goAway即可。 如果想吃满全屏,只需要将寻路调整成寻找最远路径即可。
代码 :
#include <iostream>
#include <string>
#include <cstring>
#include <conio.h>
#include <windows.h>
#include <cstdlib>
#include <ctime>
#include <iomanip>
#include <queue>
#include <stack>
#include <fstream>
using namespace std;
#define X 10
#define Y 10
enum FACE {UP_ =
0, DOWN_ =
1, LEFT_ =
2, RIGHT_ =
3};
int gameMap[X][Y];
void gotoXY(
int x,
int y) {
COORD coord = {x, y};
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
pair<
int,
int> apple;
ofstream out(
"c:\\1.txt");
class Snake {
public:
int x;
int y;
int tx;
int ty;
int food;
int point;
FACE face;
Snake(
int gameMap[X][Y]) {
init(gameMap);
}
void init(
int gameMap[X][Y]) {
x = X /
2;
y = Y /
2;
tx = -
1;
ty = -
1;
food =
0;
point =
3;
face = UP_;
gameMap[x][y] = point;
setFood(gameMap);
}
void setFace(FACE f) {
switch(face) {
case UP_:
if (f != DOWN_) {
face = f;
}
break;
case DOWN_:
if (f != UP_) {
face = f;
}
break;
case LEFT_:
if (f != RIGHT_) {
face = f;
}
break;
case RIGHT_:
if (f != LEFT_) {
face = f;
}
break;
}
}
void setFood(
int gameMap[X][Y]) {
int tempX, tempY;
srand(time(
0));
do {
tempX = rand() % (X -
1) +
1;
tempY = rand() % (X -
1) +
1;
}
while (gameMap[tempX][tempY]);
gameMap[tempX][tempY] =
2;
apple.first = tempX;
apple.second = tempY;
}
bool check(
int gameMap[X][Y],
int x,
int y) {
if (x <
0 || y <
0 || x >= X || y >= Y || (gameMap[x][y] !=
2 && gameMap[x][y] !=
0)) {
return false;
}
else {
if (gameMap[x][y] ==
2) {
food++;
setFood(gameMap);
}
return true;
}
}
bool move(
int gameMap[X][Y]) {
moveTail(gameMap);
return moveHead(gameMap);
}
bool moveHead(
int gameMap[X][Y]) {
if (tx == -
1) {
tx = x;
ty = y;
}
switch(face) {
case UP_:
y--;
break;
case DOWN_:
y++;
break;
case LEFT_:
x--;
break;
case RIGHT_:
x++;
break;
default:
getch();
break;
}
if (check(gameMap, x, y)) {
gameMap[x][y] = ++point;
return true;
}
else {
return false;
}
}
void moveTail(
int gameMap[X][Y]) {
if (food !=
0) {
food--;
return;
}
int nextX = tx;
int nextY = ty;
int fx[
4] = {
1, -
1,
0,
0};
int fy[
4] = {
0,
0, -
1,
1};
for (
int i =
0; i <
4; i++) {
if (gameMap[tx + fx[i]][ty + fy[i]] == gameMap[tx][ty] +
1) {
nextX = tx + fx[i];
nextY = ty + fy[i];
break;
}
}
gameMap[tx][ty] =
0;
tx = nextX;
ty = nextY;
}
};
Snake snake(gameMap);
void init();
void display(
int gameMap[X][Y]);
void setFood(
int gameMap[X][Y]);
void control(
int ch);
stack<int> bfs(pair<
int,
int> start, pair<
int,
int> end) {
stack<int> path;
int dist[
101][
101];
int dist2[
101][
101];
for (
int i =
0; i < X; i++) {
for (
int j =
0; j < Y; j++) {
dist[i][j] =
0x7f7f;
dist2[i][j] = -
1;
}
}
queue<pair<int, int> > que;
dist[start.first][start.second] =
0;
que.push(start);
int fx[
4] = {
0,
0, -
1,
1};
int fy[
4] = {-
1,
1,
0,
0};
while (que.size()) {
pair<
int,
int> now;
now = que.front();
que.pop();
if (now == end) {
break;
}
for (
int i =
0; i <
4; i++) {
int nx = now.first + fx[i];
int ny = now.second + fy[i];
if (nx >=
0 && ny >=
0 && nx < X && ny < Y && (gameMap[nx][ny] ==
0 || gameMap[nx][ny] == gameMap[end.first][end.second]) && dist[nx][ny] ==
0x7f7f) {
que.push(pair<
int,
int>(nx, ny));
dist2[nx][ny] = i;
dist[nx][ny] = dist[now.first][now.second] +
1;
}
}
}
out << start.first <<
"," << start.second <<
"->" << end.first <<
"," << end.second << endl;
out <<
" ";
for (
int i =
0; i < X; i++) {
out << setw(
4) << i;
}
out << endl;
for (
int i =
0; i < Y; i++) {
out << i <<
":";
for (
int j =
0; j < X; j++) {
out << setw(
4) << dist2[j][i];
}
out << endl;
}
int d = dist2[end.first][end.second];
while (d != -
1) {
path.push(d);
switch(d) {
case UP_:
d = dist2[end.first][++end.second];
break;
case DOWN_:
d = dist2[end.first][--end.second];
break;
case LEFT_:
d = dist2[++end.first][end.second];
break;
case RIGHT_:
d = dist2[--end.first][end.second];
break;
}
}
return path;
}
void moveFace(pair<
int,
int> &nowPos,
int face) {
switch(face) {
case UP_:
nowPos.second--;
break;
case DOWN_:
nowPos.second++;
break;
case LEFT_:
nowPos.first--;
break;
case RIGHT_:
nowPos.first++;
break;
}
}
pair<
int,
int> findNear(
int tx,
int ty) {
pair<
int,
int> p;
int fx[
4] = {
1, -
1,
0,
0};
int fy[
4] = {
0,
0, -
1,
1};
for (
int i =
0; i <
4; i++) {
if (gameMap[tx + fx[i]][ty + fy[i]] == gameMap[tx][ty] +
1) {
p.first = tx + fx[i];
p.second = ty + fy[i];
return p;
}
}
}
bool randomMove() {
int fy[
4] = {-
1,
1,
0,
0};
int fx[
4] = {
0,
0, -
1,
1};
int i = -
1;
vector<int> vec;
bool flag =
false;
for (i =
0; i <
4; i++) {
if (gameMap[snake.x + fx[i]][snake.y + fy[i]] ==
0) {
pair<
int,
int> nowPos(snake.x + fx[i], snake.y + fy[i]);
stack<int> path = bfs(nowPos, pair<
int,
int>(snake.tx, snake.ty));
if (!path.empty()) {
flag =
true;
break;
}
vec.push_back(i);
}
}
if (!flag) {
if (vec.size() !=
0) {
i = vec[
0];
}
}
if (i != -
1 && i !=
4) {
snake.setFace((FACE)i);
snake.move(gameMap);
display(gameMap);
return true;
}
else {
return false;
}
}
bool goAway() {
pair<
int,
int> nowPos(snake.x, snake.y);
stack<int> path = bfs(nowPos, pair<
int,
int>(snake.tx, snake.ty));
if (!path.empty()) {
snake.setFace((FACE)path.top());
snake.move(gameMap);
display(gameMap);
return true;
}
else {
randomMove();
return true;
}
return false;
}
bool autoMove(
int gameMap[X][Y]) {
pair<
int,
int> nowPos(snake.x, snake.y);
stack<int> path = bfs(nowPos, apple);
if (!path.empty()) {
moveFace(nowPos, (FACE)path.top());
if (snake.tx != -
1) {
int temp = gameMap[apple.first][apple.second];
gameMap[apple.first][apple.second] =
0;
stack<int> path2 = bfs(nowPos, pair<
int,
int>(snake.tx, snake.ty));
gameMap[apple.first][apple.second] = temp;
if (!path2.empty()) {
int d = path.top();
snake.setFace((FACE)d);
snake.move(gameMap);
display(gameMap);
}
else {
goAway();
}
}
else {
snake.setFace((FACE)path.top());
snake.move(gameMap);
display(gameMap);
}
}
else {
goAway();
}
return true;
}
int main()
{
init();
display(gameMap);
while (
true) {
if (kbhit()) {
char a = getch();
control(a);
}
if (autoMove(gameMap) ==
false) {
return 0;
}
}
return 0;
}
void init() {
memset(gameMap,
0,
sizeof(gameMap));
for (
int y =
0; y < Y; y++) {
for (
int x =
0; x < X; x++) {
if (x ==
0 || y ==
0 || x == X -
1 || y == Y -
1) {
gameMap[x][y] = -
99;
}
}
}
snake.init(gameMap);
}
void display(
int gameMap[X][Y]) {
for (
int y =
0; y < Y; y++) {
for (
int x =
0; x < X; x++) {
gotoXY(x *
2, y);
switch(gameMap[x][y]) {
case 0:
cout <<
" ";
break;
case -
99:
cout <<
"■";
break;
case 2:
cout <<
"★";
break;
default:
cout <<
"□";
break;
}
}
}
gotoXY(snake.tx *
2, snake.ty);
cout <<
"☆";
gotoXY(
0,
15);
gotoXY(snake.x *
2, snake.y);
cout <<
"●";
}
void setFood(
int gameMap[X][Y]) {
int tempX, tempY;
srand(time(
0));
do {
tempX = rand() % (X -
1) +
1;
tempY = rand() % (X -
1) +
1;
}
while (gameMap[tempX][tempY]);
gameMap[tempX][tempY] =
2;
}
void control(
int ch) {
switch(ch) {
case 'w':
case 'W':
if (snake.face != DOWN_) {
snake.setFace(UP_);
}
break;
case 'a':
case 'A':
if (snake.face != RIGHT_) {
snake.setFace(LEFT_);
}
break;
case 'd':
case 'D':
if (snake.face != LEFT_) {
snake.setFace(RIGHT_);
}
break;
case 's':
case 'S':
if (snake.face != UP_) {
snake.setFace(DOWN_);
}
break;
}
}