java 人机对战五子棋

import java.awt.*;
import java.awt.event.*;
import java.net.URL;

import javax.swing.*;

public class GobangGame {
	public static void main(String[] args) {
		GameF game = new GameF();
		game.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		game.show();
	}
}

class GameF extends JFrame {
	public GameF() {
		Container contentPane = getContentPane();
		final Panel panel = new Panel();
		panel.setBackground(new Color(255, 182, 147));
		contentPane.setBackground(new Color(255, 182, 147));
		contentPane.add(panel);
		setSize(560, 560);
		setTitle("五子棋游戏 版本1.0");
		setResizable(false);
		panel.setCursor(new Cursor(Cursor.HAND_CURSOR));
		JMenuBar menuBar = new JMenuBar();
		JMenu menu = new JMenu("选项");
		JMenuItem menuStart = new JMenuItem("开始游戏");
		menuStart.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				panel.ResetGame();
				panel.repaint();
			}
		});
		JMenuItem menuExit = new JMenuItem("退出");
		menuExit.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				System.exit(0);
			}
		});
		menuBar.add(menu);
		menu.add(menuStart);
		menu.add(menuExit);
		this.setJMenuBar(menuBar);
	}
}

class Panel extends JPanel {
	private URL blackImgURL = GobangGame.class.getResource("black.gif");

	private ImageIcon black = new ImageIcon(blackImgURL);

	private URL whiteImgURL = GobangGame.class.getResource("white.gif");

	private ImageIcon white = new ImageIcon(whiteImgURL);

	private URL currentImgURL = GobangGame.class.getResource("current.gif");

	private ImageIcon current = new ImageIcon(currentImgURL);

	private int i, j, k, m, n, icount;

	private int[][] board = new int[16][16];

	private boolean[][][] ptable = new boolean[16][16][672];

	private boolean[][][] ctable = new boolean[16][16][672];

	private int[][] cgrades = new int[16][16];

	private int[][] pgrades = new int[16][16];

	private int cgrade, pgrade;

	private int[][] win = new int[2][672];

	private int oldx, oldy;

	private int bout = 1;

	private int pcount, ccount;

	private boolean player, computer, over, pwin, cwin, tie, start;

	private int mat, nat, mde, nde;

	public Panel() {
		addMouseListener(new Xiazi());
		this.ResetGame();
	}

	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		for (int i = 0; i < 16; i++)
			for (int j = 0; j < 16; j++) {
				g.drawLine(50, 50 + j * 30, 500, 50 + j * 30);
			}
		for (int i = 0; i < 16; i++)
			for (int j = 0; j < 16; j++) {
				g.drawLine(50 + j * 30, 50, 50 + j * 30, 500);
			}
		for (int i = 0; i < 16; i++) {
			String number = Integer.toString(i);
			g.drawString(number, 46 + 30 * i, 45);
		}
		for (int i = 1; i < 16; i++) {
			String number = Integer.toString(i);
			g.drawString(number, 33, 53 + 30 * i);
		}
		updatePaint(g);
	}

	class Xiazi extends MouseAdapter {
		public void mouseClicked(MouseEvent e) {
			if (!over) {
				oldx = e.getX();
				oldy = e.getY();
				mouseClick();
				repaint();
			}
		}
	}

	// 游戏初始化
	public void ResetGame() {
		// 初始化棋盘
		for (i = 0; i < 16; i++)
			for (j = 0; j < 16; j++) {
				this.pgrades[i][j] = 0;
				this.cgrades[i][j] = 0;
				this.board[i][j] = 2;
			}
		// 遍历所有的五连子可能情况的权值
		// 横
		for (i = 0; i < 16; i++)
			for (j = 0; j < 12; j++) {
				for (k = 0; k < 5; k++) {
					this.ptable[j + k][i][icount] = true;
					this.ctable[j + k][i][icount] = true;
				}
				icount++;
			}
		// 竖
		for (i = 0; i < 16; i++)
			for (j = 0; j < 12; j++) {
				for (k = 0; k < 5; k++) {
					this.ptable[i][j + k][icount] = true;
					this.ctable[i][j + k][icount] = true;
				}
				icount++;
			}
		// 右斜
		for (i = 0; i < 12; i++)
			for (j = 0; j < 12; j++) {
				for (k = 0; k < 5; k++) {
					this.ptable[j + k][i + k][icount] = true;
					this.ctable[j + k][i + k][icount] = true;
				}
				icount++;
			}
		// 左斜
		for (i = 0; i < 12; i++)
			for (j = 15; j >= 4; j--) {
				for (k = 0; k < 5; k++) {
					this.ptable[j - k][i + k][icount] = true;
					this.ctable[j - k][i + k][icount] = true;
				}
				icount++;
			}
		for (i = 0; i <= 1; i++)
			// 初始化黑子白子上的每个权值上的连子数
			for (j = 0; j < 672; j++)
				this.win[i][j] = 0;
		this.player = true;
		this.icount = 0;
		this.ccount = 0;
		this.pcount = 0;
		this.start = true;
		this.over = false;
		this.pwin = false;
		this.cwin = false;
		this.tie = false;
		this.bout = 1;
	}

	public void ComTurn() { // 找出电脑(白子)最佳落子点
		for (i = 0; i <= 15; i++)
			// 遍历棋盘上的所有坐标
			for (j = 0; j <= 15; j++) {
				this.pgrades[i][j] = 0; // 该坐标的黑子奖励积分清零
				if (this.board[i][j] == 2) // 在还没下棋子的地方遍历
					for (k = 0; k < 672; k++)
						// 遍历该棋盘可落子点上的黑子所有权值的连子情况,并给该落子点加上相应奖励分
						if (this.ptable[i][j][k]) {
							switch (this.win[0][k]) {
							case 1: // 一连子
								this.pgrades[i][j] += 5;
								break;
							case 2: // 两连子
								this.pgrades[i][j] += 50;
								break;
							case 3: // 三连子
								this.pgrades[i][j] += 180;
								break;
							case 4: // 四连子
								this.pgrades[i][j] += 400;
								break;
							}
						}
				this.cgrades[i][j] = 0;// 该坐标的白子的奖励积分清零
				if (this.board[i][j] == 2) // 在还没下棋子的地方遍历
					for (k = 0; k < 672; k++)
						// 遍历该棋盘可落子点上的白子所有权值的连子情况,并给该落子点加上相应奖励分
						if (this.ctable[i][j][k]) {
							switch (this.win[1][k]) {
							case 1: // 一连子
								this.cgrades[i][j] += 5;
								break;
							case 2: // 两连子
								this.cgrades[i][j] += 52;
								break;
							case 3: // 三连子
								this.cgrades[i][j] += 100;
								break;
							case 4: // 四连子
								this.cgrades[i][j] += 400;
								break;
							}
						}
			}
		if (this.start) { // 开始时白子落子坐标
			if (this.board[4][4] == 2) {
				m = 4;
				n = 4;
			} else {
				m = 5;
				n = 5;
			}
			this.start = false;
		} else {
			for (i = 0; i < 16; i++)
				for (j = 0; j < 16; j++)
					if (this.board[i][j] == 2) { // 找出棋盘上可落子点的黑子白子的各自最大权值,找出各自的最佳落子点
						if (this.cgrades[i][j] >= this.cgrade) {
							this.cgrade = this.cgrades[i][j];
							this.mat = i;
							this.nat = j;
						}
						if (this.pgrades[i][j] >= this.pgrade) {
							this.pgrade = this.pgrades[i][j];
							this.mde = i;
							this.nde = j;
						}
					}
			if (this.cgrade >= this.pgrade) { // 如果白子的最佳落子点的权值比黑子的最佳落子点权值大,则电脑的最佳落子点为白子的最佳落子点,否则相反
				m = mat;
				n = nat;
			} else {
				m = mde;
				n = nde;
			}
		}
		this.cgrade = 0;
		this.pgrade = 0;
		this.board[m][n] = 1; // 电脑下子位置
		ccount++;
		if ((ccount == 50) && (pcount == 50)) // 平局判断
		{
			this.tie = true;
			this.over = true;
		}
		for (i = 0; i < 672; i++) {
			if (this.ctable[m][n][i] && this.win[1][i] != 7)
				this.win[1][i]++; // 给白子的所有五连子可能的加载当前连子数
			if (this.ptable[m][n][i]) {
				this.ptable[m][n][i] = false;
				this.win[0][i] = 7;
			}
		}
		this.player = true; // 该人落子
		this.computer = false; // 电脑落子结束
	}

	public void mouseClick() {
		if (!this.over)
			if (this.player) {
				if (this.oldx < 520 && this.oldy < 520) {
					int m1 = m, n1 = n;
					m = (oldx - 33) / 30;
					n = (oldy - 33) / 30;
					if (this.board[m][n] == 2) {
						this.bout++;
						this.board[m][n] = 0;
						pcount++;
						if ((ccount == 50) && (pcount == 50)) {
							this.tie = true;
							this.over = true;
						}
						for (i = 0; i < 672; i++) {
							if (this.ptable[m][n][i] && this.win[0][i] != 7)
								this.win[0][i]++; // 给黑子的所有五连子可能的加载当前连子数
							if (this.ctable[m][n][i]) {
								this.ctable[m][n][i] = false;
								this.win[1][i] = 7;
							}
						}
						this.player = false;
						this.computer = true;
					} else {
						m = m1;
						n = n1;
					}
				}
			}
	}

	public void updatePaint(Graphics g) {
		if (!this.over) { // 如果是轮到电脑下
			if (this.computer)
				this.ComTurn(); // 得到最佳下子点
			// 遍历当前棋盘上的五连子情况,判断输赢
			for (i = 0; i <= 1; i++)
				for (j = 0; j < 672; j++) {
					if (this.win[i][j] == 5)
						if (i == 0) { // 人赢
							this.pwin = true;
							this.over = true; // 游戏结束
							break;
						} else {
							this.cwin = true; // 电脑赢
							this.over = true;
							break;
						}
					if (this.over) // 一遇到五连子退出棋盘遍历
						break;
				}
			g.setFont(new Font("华文行楷", 0, 20));
			g.setColor(Color.RED);
			// 画出当前棋盘所有棋子
			for (i = 0; i <= 15; i++)
				for (j = 0; j <= 15; j++) { // 如果board元素值为0,则该坐标处为黑子
					if (this.board[i][j] == 0) {
						g.drawImage(black.getImage(), i * 30 + 31, j * 30 + 31,
								black.getImage().getWidth(
										black.getImageObserver()) - 3, black
										.getImage().getHeight(
												black.getImageObserver()) - 3,
								black.getImageObserver());
					}
					// 如果board元素值为1,则该坐标处为白子
					if (this.board[i][j] == 1) {
						g.drawImage(white.getImage(), i * 30 + 31, j * 30 + 31,
								white.getImage().getWidth(
										white.getImageObserver()) - 3, white
										.getImage().getHeight(
												white.getImageObserver()) - 3,
								white.getImageObserver());
					}
				}
			// 画出白子(电脑)当前所下子,便于辨认
			if (this.board[m][n] != 2)
				g
						.drawImage(current.getImage(), m * 30 + 31,
								n * 30 + 31, current.getImage().getWidth(
										current.getImageObserver()) - 4,
								current.getImage().getHeight(
										current.getImageObserver()) - 4,
								current.getImageObserver());
			// 判断输赢情况
			// 人赢
			if (this.pwin)
				g.drawString("您太厉害了!再来一次请重新开始游戏..", 20, 200);
			// 电脑赢
			if (this.cwin)
				g.drawString("很遗憾,你输了!再来一次请重新开始游戏..", 84, 190);
			// 平局
			if (this.tie)
				g.drawString("不分胜负!再来一次请重新开始游戏..", 80, 200);
			g.dispose();
		}
	}
}

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