AI贪吃蛇( JAVA版)+A*寻路算法

代码目标
有一条AI蛇,可以自己寻路,吃食物,并且符合基本规则,上下键控制蛇的速度,空格键实现开始和暂停

(悄悄的告诉你,这个代码,运气好,可以吃满屏,运气不好,一会就…你懂得,嘿嘿嘿)

代码结构
首先,我们需要创建5个类
1,Test.class
这个是用来创建窗口的,就是我们看到的画面

2,SnakePan.class(主要)
这个是用来画我们所看到的所有的图画。比如说蛇头,蛇身,食物…

3,.Node.class
是一个抽象类,下面的蛇和食物都是他的子类

4,Snake.class(主要)
就是一条蛇,可以移动,可以自动寻路

5,Food.class
就是食物,没啥可说的
在这里插入图片描述
日常搞怪,别介意

核心思想
1)首先要想确定一条蛇,可由蛇头,蛇尾,身体构成,食物单独拿出来。
2)接下来讲思想:
蛇的走位算法:

if(蛇头可以到达食物) {
	if(蛇头尝试走一步依然可以到达蛇尾) {
		蛇就可以真的走一步
	}else {
		蛇头去找蛇尾
	}
}else {
	蛇头去找蛇尾
}

A*寻路算法:
就是一直着离终点做小的距离的点,不懂可以去bibilili上搜一下
(由于我太菜,讲的不是太清楚)
图片资源
由于上传图片后,下载需要积分,我想了想,还是算了,直接就放在这里了,如果你是电脑高手,你知道怎么拿走的。(嘻嘻嘻)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
游戏代码
1,

package snake01;

import javax.swing.JFrame;

public class Test {

	public static void main(String[] args) {
		JFrame jf = new JFrame("AI贪吃蛇");
		jf.setBounds(400, 200, 782, 810);
		jf.setResizable(false);
		jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		SankePan pan = new SankePan();
		jf.add(pan);
		jf.setVisible(true);
	}

}

2,

package snake01;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;

import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.Timer;

import com.sun.org.apache.xerces.internal.util.SynchronizedSymbolTable;

public class SankePan extends JPanel implements KeyListener,ActionListener{
	
	ImageIcon up = new ImageIcon("up.png");
	ImageIcon down = new ImageIcon("down.png");
	ImageIcon left = new ImageIcon("left.png");
	ImageIcon right = new ImageIcon("right.png");
	ImageIcon title = new ImageIcon("title.jpg");
	ImageIcon fod = new ImageIcon("food.png");
	ImageIcon body = new ImageIcon("body.png");
	
	Snake snake;
	Food food;
	boolean pass = false;
	
	Random r=new Random();
	Timer ti = new Timer(101,this);
	
	
	public SankePan() {
		this.setFocusable(true);
		this.addKeyListener(this);
		snake=new Snake();
		food=new Food(snake.mp);
	}
	
	public void paint(Graphics g) {
		super.paint(g);
		this.setBackground(Color.BLACK);
		for (int i = 1; i < snake.len; i++) {
			body.paintIcon(this, g, snake.s[i][1] * 25, snake.s[i][0] * 25);
		}
		if (snake.dir == 3) {
			right.paintIcon(this, g, snake.s[0][1] * 25, snake.s[0][0] * 25);
		} else if (snake.dir == 1) {
			left.paintIcon(this, g, snake.s[0][1] * 25, snake.s[0][0] * 25);
		} else if (snake.dir == 2) {
			up.paintIcon(this, g, snake.s[0][1] * 25, snake.s[0][0] * 25);
		} else if (snake.dir == 4) {
			down.paintIcon(this, g, snake.s[0][1] * 25, snake.s[0][0] * 25);
		}
		fod.paintIcon(this, g, food.y * 25, food.x * 25);
	}

	
	@Override
	public void keyTyped(KeyEvent e) {
	}
	@Override
	public void keyPressed(KeyEvent e) {
		int key=e.getKeyCode();
		System.out.println(key);
		if(key==32) {
			pass=!pass;
			if(pass==true) ti.start();
			else ti.stop();
		}else if(key==40) {
			if(ti.getDelay()>10) {
				ti.setDelay(ti.getDelay()-10);
			}
		}else if(key==38) {
			ti.setDelay(ti.getDelay()+10);
		}
		System.out.println("当前速度:"+ti.getDelay());
		this.repaint();
	}
	@Override
	public void keyReleased(KeyEvent e) {
	}
	@Override
	public void actionPerformed(ActionEvent e) {
		int a1=snake.getHead().x;
		int a2=snake.getHead().y;
		int b1=snake.getTail().x;
		int b2=snake.getTail().y;
		int f1=food.x;
		int f2=food.y;
		Node node1=snake.afs(f1,f2,a1,a2);
		Node node2=null;
		if(node1!=null) {
			node2=snake.afs(b1, b2, node1.x, node1.y);	
			if(node2==null) {
				node1=snake.afs(b1, b2, a1, a2);
			}
		}else {
			node1=snake.afs(b1, b2, a1, a2);
		}	
		snake.mp[f1][f2]=1; 
		a1=node1.x;
		a2=node1.y;
		if(a1==f1&&a2==f2) {
			snake.run(a1, a2, 1);
			food=new Food(snake.mp);
		}else {
			snake.run(a1, a2, 0);
		}
		repaint();
	}
}

3,

package snake01;

public class Node implements Comparable{
	int x,y;
	int num;
	Node(){
	}
	Node(int x,int y){
		this.x=x;
		this.y=y;
	}
	Node(int x,int y,int tx,int ty){
		this.x=x;
		this.y=y;
		num=Math.abs(x-tx)+Math.abs(y-ty);
	}
	public int compareTo(Node other) {
		return num-other.num;
	}
	
}

4,

package snake01;

import java.util.PriorityQueue;
import java.util.Vector;

public class Snake {

	int[][] s;
	int len, dir;
	int[][] mp, np;
	int[][] to = { { 1, 0 }, { -1, 0 }, { 0, -1 }, { 0, 1 } };

	public Snake() {
		dir = 3;
		mp = new int[35][35];
		s = new int[900][2];
		len = 3;
		s[0][0] = 1;
		s[0][1] = 3;
		s[1][0] = 1;
		s[1][1] = 2;
		s[2][0] = 1;
		s[2][1] = 1;
		mp[1][1] = 1;
		mp[1][2] = 1;
		mp[1][3] = 1;
	}

	public void run(int x, int y, int t) {
		if (t == 1) {
			len++;
		}else {
			mp[s[len-1][0]][s[len-1][1]]=0;
		}
		mp[x][y]=1;
		for (int i = len - 1; i > 0; i--) {
			s[i][0] = s[i - 1][0];
			s[i][1] = s[i - 1][1];
		}
		
		if(s[0][0] - x<0) {
			dir=4;
		}else if(s[0][0] - x>0) {
			dir=2;
		}else if(s[0][1] - y<0) {
			dir=3;
		}else if(s[0][1] - y>0) {
			dir=1;
		}
		
		s[0][0] = x;
		s[0][1] = y;
	}

	public Node getHead() {
		return new Node(s[0][0],s[0][1]);
	}
	
	public Node getTail() {
		return new Node(s[len-1][0],s[len-1][1]);
	}
	public Node getLastTail() {
		return new Node(s[len-2][0],s[len-2][1]);
	}
	
	public Node afs(int x1, int y1, int x2,int y2) {
		
		PriorityQueue pq = new PriorityQueue<>();
		int[][] np = new int[35][35];
		np[x1][y1]=1; 
		Node no=new Node(x1, y1, x2, y2);
		pq.add(no);
		
		while (pq.size() != 0) {
			Node node = pq.remove();
			
			for (int i = 0; i < 4; i++) {
				int tx = node.x + to[i][0];
				int ty = node.y + to[i][1];
				if(tx == x2 && ty == y2) {
					return node;
				}
				if (tx < 0 || tx >= 30 || ty < 0 || ty >= 30||np[tx][ty] == 1||mp[tx][ty] == 1) {
					continue;
				}
				np[tx][ty] = 1;
				Node n = new Node(tx, ty, x2, y2);
				pq.add(n);
			}
		}

		return null;
	}

}

5,

package snake01;

import java.util.Random;

public class Food extends Node {

	public Food(int[][] mp) {
		Random r = new Random();
		int x = r.nextInt(30);
		int y = r.nextInt(30);
		while (mp[x][y] == 1) {
			x = r.nextInt(30);
			y = r.nextInt(30);
		}
		this.x = x;
		this.y = y;
	}

}

你可能感兴趣的:(java,游戏)