前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java版五子棋小游戏(java控制台)

Java版五子棋小游戏(java控制台)

作者头像
Fivecc
发布2022-11-21 16:27:09
1.2K0
发布2022-11-21 16:27:09
举报
文章被收录于专栏:前端ACE

                       Java版五子棋小游戏(java控制台)

前言: 该项目 为 Java 版五子棋小游戏,为控制台小游戏,主要功能有 人机大战,左右互战,可以悔棋可以提示,

人机大战采用 五元贡献法,代码简单 实况效果好 ,相比 一般 博弈论 判断局面的方式,比正真的AI 还是有一定的差距。还有更多可扩展 可以自行摸索

源码:https://github.com/Five-great/FiveChess

核心代码:

代码语言:javascript
复制
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.*;
//游戏运行入口
public class FiveChess{public static void main(String[] args){new FiveChessMenu();}}
//界面类,这是游戏主体框架
class FiveChessWindows extends JFrame {//五子棋窗口
	private Chessboard chessboard = new Chessboard();//五子棋盘【关键】
	private Chess chess = new Chess();	//五子棋业务逻辑【关键】	
	private Panel toolbar1,toolbar2,toolbar3;	
	private boolean flag;//
	private JButton startButton;
	private JTextField text1, text2,text3,text4;
	private JButton prompt1,prompt2;
	private JButton backButton1,backButton2;
	private JButton exitButton;
	private int owner_flag=1;//用于左右互搏
	private boolean prompt_flag=false;
	private String utf_hz = null,utf_bz=null; //
	//完成五子棋游戏界面
	public void init(Boolean flag,int res_flag){
		this.flag=flag;Chess.FIRST=res_flag;
		setTitle("java版五子棋-five");//创建游戏界面窗口
		toolbar1 = new Panel();
		toolbar2 = new Panel();
		toolbar3 = new Panel();
		toolbar1.setLayout(new GridLayout(3,1,20,20));
		toolbar3.setLayout(new GridLayout(3,1,20,20));
		text1 = new JTextField();
		text1.setPreferredSize(new Dimension(60, 60)); // 设置大小
		text1.setFont(new Font(null, Font.BOLD,50));
		text1.setEditable(false);//设置不可编辑
		text2 = new JTextField();
		text2.setPreferredSize(new Dimension(60, 60)); // 设置大小
		text2.setFont(new Font(null, Font.BOLD,50));
		text2.setEditable(false);//设置不可编辑
		text3 = new JTextField();
		text3.setPreferredSize(new Dimension(60, 60)); // 设置大小
		text3.setFont(new Font(null, Font.BOLD,50));
		text3.setEditable(false);//设置不可编辑
		text4 = new JTextField();
		text4.setPreferredSize(new Dimension(60, 60)); // 设置大小
		text4.setFont(new Font(null, Font.BOLD,50));
		text4.setEditable(false);//设置不可编辑
		//把“选项”菜单加入到菜单栏
		//MyButton startButton= new MyButton("       重   新    开     始           ");
		startButton = new MyButton("       重     新    开     始           ");
		backButton1 = new MyButton("       悔      棋         ");
		backButton2 = new MyButton("       悔      棋         ");
		prompt1 = new MyButton("   提        ?      示       ");
		prompt2 = new MyButton("   提        ?      示       ");
		exitButton = new MyButton("        返     回    菜    单             ");
		toolbar1.setBackground(Color.cyan);
		toolbar2.setBackground(Color.green);
		toolbar3.setBackground(Color.cyan);
		if(!flag)toolbar1.add(new JLabel(new ImageIcon("./src/玩家.png")));
		else toolbar1.add(new JLabel(new ImageIcon("./src/电脑1.png")));
		toolbar3.add(new JLabel(new ImageIcon("./src/玩家.png")));
		JPanel j3 =new JPanel(new GridLayout(2,1,5,5));
		j3.add(text1);j3.add(text3);
		toolbar1.add(j3);
		if(!flag)text1.setText("—玩 家—");
		else text1.setText("—电 脑—");
		JPanel j4 =new JPanel(new GridLayout(2,1,5,5));
		j4.add(text2);j4.add(text4);
		toolbar3.add(j4);
		text2.setText("—玩 家—");
		JPanel j1=new JPanel();
		 j1.setLayout(new GridLayout(3,1,20,20));
		 j1.setBackground(Color.cyan);
		 j1.add(prompt1);
		 j1.add(backButton1);
		 toolbar1.add(j1);
		 JPanel j2=new JPanel();
		 j2.setLayout(new GridLayout(3,1,20,20));//网格布局
		 j2.setBackground(Color.cyan);
		 j2.add(prompt2);
		 j2.add(backButton2);
		 toolbar3.add(j2);
		 exitButton.setSize(180, 60);
		toolbar2.add(startButton);
		toolbar2.add(exitButton);
		Gbk_Utf1();
		textInit();
		ButtonInit();//按钮事件绑定初始化
			add(toolbar1, BorderLayout.WEST);
			add(toolbar2, BorderLayout.SOUTH);
			add(toolbar3, BorderLayout.EAST);
			add(chessboard,BorderLayout.CENTER);//把五子棋盘加入到frame
			//绑定鼠标事件,要下棋了,为了避免写无用的抽象方法的实现,
			chessboard.addMouseListener(new MouseAdapter(){
				public void mouseClicked(MouseEvent e){
					play(e);//鼠标点击引发下棋事件,处理下棋事件比较繁琐,为此开一个方法
				}
			});	
		//设置frame窗口左上角图标
		 setIconImage(this.getToolkit().getImage("./src/favicon.png"));
		 setLocation(225, 100);
		 setSize(1198, 800);
		 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		 setResizable(false);
		 setVisible(true);
		 AIFirstOptionInit();//
	}
	public void ButtonInit() {
		backButton1.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				int xy=chessboard.goback();
				if(xy>0)chess.goback(xy);
			}
		});
		backButton2.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
			    // goback();
				int xy=chessboard.goback();
				if(xy>0)chess.goback(xy);
			}
		});
		prompt1.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				prompt_flag=!prompt_flag;
				chessboard.setPrompt(prompt_flag);
				if(prompt_flag) chessboard.setScores(chess.getScores());
				chessboard.repaint();
				
			}
		});	
		prompt2.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				prompt_flag=!prompt_flag;
				chessboard.setPrompt(prompt_flag);
				if(prompt_flag) {chessboard.setScores(chess.getScores());}
				chessboard.repaint();
			}
		});	
		exitButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				new FiveChessMenu();
                dispose();
			}
		});	
			
		startButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				FiveChessWindows five = new FiveChessWindows();
				  five.init(flag,1);
				  new RockPaperScissors(flag,five);
				  dispose();
			}
		});	
	}
	//“先后手处理事件
	public void AIFirstOptionInit(){
				//棋盘还没有落子的时候可以选择“机器先手”,一旦有落子,选择“机器先手”失效
				if(chessboard.isEmpty()){
					if(Chess.FIRST ==-1) {
					//机器先手,则先在中间位置下一个棋子
					chessboard.addChessman(7, 7, -1);
					chess.addChessman(7, 7, -1);
				}
	}
}
	public void Gbk_Utf1() {
		try {
				utf_hz= new String("⚫".getBytes("UTF-8"), "UTF-8");
				utf_bz = new String("⚪".getBytes("UTF-8"), "UTF-8");
			} catch (UnsupportedEncodingException e1) {e1.printStackTrace();}
	}
	public void textInit() {
		if(Chess.FIRST==-1) {text3.setText(" 先手"+utf_hz);text4.setText(" 后手 "+utf_bz);}
		else {text3.setText(" 后手 "+utf_bz);text4.setText(" 先手 "+utf_hz);}
	}
	//核心业务逻辑  处理鼠标落子事件
	public void play(MouseEvent e){
		int cellSize = chessboard.getCellSize();//每个格子的边长
		int x = (e.getX() - 5) / cellSize;//像素值转换成棋盘坐标
		int y = (e.getY() - 5) / cellSize;//像素值转换成棋盘坐标
		//判断落子是否合法
		boolean isLegal = chess.isLegal(x, y);
		//如果落子合法
		if(isLegal){
			chessboard.addChessman(x, y, owner_flag);//界面方面加一个棋子
			chess.addChessman(x, y, owner_flag);//逻辑业务方面加一个棋子
			//判断人类是否胜利
			if(chess.isWin(x, y, owner_flag)){
				 chessboard.setIsWin(chess.getisWinChess());
				 JOptionPane.showMessageDialog(this, "                   己方获胜", "您赢了!", JOptionPane.PLAIN_MESSAGE);
				chessboard.init();//初始化
				chess.init();
				textInit();
				return;
			}
			Location loc = chess.searchLocation();//根据五元贡献的方法确定
			if(flag) {
				//机器落子
				//Location loc = chess.searchLocation();//根据五元贡献的方法确定
				chessboard.addChessman(loc);
				chess.addChessman(loc.getX(), loc.getY(), loc.getOwner());
				//判断机器是否胜利
				if(chess.isWin(loc.getX(), loc.getY(), -1)){
					chessboard.setIsWin(chess.getisWinChess());
					JOptionPane.showMessageDialog(this, "             对方获胜", "您输了!", JOptionPane.PLAIN_MESSAGE);
					chessboard.init();
					chess.init();
					textInit();
					return;
				}
			}else owner_flag=-owner_flag;
			chessboard.setPrompt(prompt_flag);//更行提示分数和棋子
			 chess.searchLocation();chessboard.setScores(chess.getScores());
		}
	} 
}
 class Chessboard extends JPanel{//棋盘类 继承了 JPanel
	private static final long serialVersionUID = 1L;
	public static final int CHESSBOARD_SIZE = 15;//棋盘大小15X15
	private ArrayList<Location> locationList = new ArrayList<>();//棋盘上所有可以落子的位置坐标等信息
	private Color backgroundColor = new Color(255, 245, 186);//棋盘背景色
	private Color lineColor = new Color(66, 66, 66);//棋盘线条颜色
	private int margin = 30;//棋盘边缘长度
	private int[][] scores;//获取胜利棋子;
	private int[] iswinxy;
	private boolean prompt_flag=false;
	public void init(){locationList.clear();repaint();}	//初始化棋盘
	public void setPrompt(boolean prompt_flag2) {this.prompt_flag=prompt_flag2;}//获取是否提示状态
	public void setScores(int[][] scores) {this.scores=scores;}//获取分数数据
	public void setIsWin(int[] iswinxy) {this.iswinxy=iswinxy;}
	public void paint(Graphics g){//覆盖paint方法
		super.paint(g);
		drawChessboard(g);//画棋盘
		drawScores(g);//画分数
		drawiswin(g);//画胜利棋子
		drawChessman(g);//画棋子
	}
	public void drawChessboard(Graphics g){//画棋盘
		
		g.setColor(backgroundColor);//先画背景
		g.fillRect(0, 0, this.getWidth(), this.getHeight());
		g.setColor(lineColor);//画线
		int cellSize = (this.getWidth() - 2*margin)/(CHESSBOARD_SIZE - 1);//每个格子的边长
		for(int i = 0; i < CHESSBOARD_SIZE; i++){
			g.drawLine(margin, margin + i*cellSize,this.getWidth() - margin, margin + i*cellSize);//画横线
			g.drawLine(margin + i*cellSize, margin, margin + i*cellSize, this.getHeight() -margin);//画纵线
		}
	}
	public void drawChessman(Graphics g){//画棋子
		for(int i = 0; i < locationList.size(); i++){
			Location loc = locationList.get(i);
			int cellSize = (this.getWidth() - 2*margin)/(CHESSBOARD_SIZE - 1);//每个格子的边长
		  if(i==locationList.size()-1) {
				g.setColor(new Color(207,13,62));// 标记最后一个棋子四周为红色
				g.fillRoundRect(margin + cellSize*loc.getX() - cellSize/2-5, margin + cellSize*loc.getY() - cellSize/2-5, cellSize+8, cellSize+8,100,100);
				g.setColor(backgroundColor);
				g.fillRoundRect(margin + cellSize*loc.getX() - cellSize/2-2, margin + cellSize*loc.getY() - cellSize/2-2, cellSize+2, cellSize+2,100,100);
			}	 
		    //根据先后手设置棋子为黑色和白色
			if(loc.getOwner() == Chess.FIRST)g.setColor(Color.BLACK);
		    else g.setColor(Color.WHITE);	//画棋子
			g.fillOval(margin + cellSize*loc.getX() - cellSize/2+3, margin + cellSize*loc.getY() - cellSize/2+3, cellSize-6, cellSize-6);

		}
	}
  //划分数
	public void drawScores(Graphics g) {
		if(prompt_flag) {
		   int Maxscore=0,Maxx=-1,Maxy=-1;
		  g.setColor(Color.darkGray);
		  int cellSize = (this.getWidth() - 2*margin)/(CHESSBOARD_SIZE - 1);//每个格子的边长
		  for(int i = 0; i < CHESSBOARD_SIZE; i++)
			for(int j = 0; j < CHESSBOARD_SIZE; j++) {
				if(Maxscore<=scores[i][j]){Maxscore=scores[i][j];Maxx=i;Maxy=j;}
				g.drawString(""+scores[i][j],margin + i*cellSize, margin + j*cellSize);
		  }
		  g.setColor(Color.green);//画提示棋子。
		  g.fillOval(margin + cellSize*Maxx - cellSize/2+5, margin + cellSize*Maxy - cellSize/2+5, cellSize-8, cellSize-8);
		}
	}		
		public void drawiswin(Graphics g) { //画胜利棋子
			 if(iswinxy!=null && iswinxy.length>3) {
			  g.setColor(Color.darkGray);System.out.println(iswinxy.length);
			  int cellSize = (this.getWidth() - 2*margin)/(CHESSBOARD_SIZE - 1);//每个格子的边长
			  int x1,y1;
			  for(int i=0;i<5;i++) {
			     x1=iswinxy[i]/100;y1=iswinxy[i]%100;
			    g.setColor(new Color(207,13,62));//
				g.fillRoundRect(margin + cellSize*x1 - cellSize/2-5, margin + cellSize*y1 - cellSize/2-5, cellSize+8, cellSize+8,100,100);
				g.setColor(backgroundColor);
				g.fillRoundRect(margin + cellSize*x1 - cellSize/2-2, margin + cellSize*y1 - cellSize/2-2, cellSize+2, cellSize+2,100,100);
			  }	
			  iswinxy=null;
		  }  
		}	
	public int goback() {
		if (locationList.size() == 0)return -1;
		int x=locationList.get(locationList.size()-1).getX();
		int y=locationList.get(locationList.size()-1).getY();
		locationList.remove(locationList.size()-1);repaint();
		return x*100+y;
	}
	public void addChessman(int x, int y, int owner){locationList.add(new Location(x, y, owner));repaint();}//落子
	public void addChessman(Location loc){locationList.add(loc);repaint();}
	public int getCellSize(){return (this.getWidth() - 2*margin)/(CHESSBOARD_SIZE - 1);}//计算棋盘每个小格子的大小
	public boolean isEmpty() {return locationList.size() == 0 ? true : false;}//判断棋盘是否还没有棋子
}
class Location{
	private int x;//某个棋盘位置横坐标,0-14
	private int y;//某个棋盘位置纵坐标,0-14
	private int owner;//占据该位置的棋手方,1是人类,-1是机器,0是空
	private int score;//对该位置的打的分数
	public Location(){}//构造方法
	public Location(int x, int y, int owner){this.x = x;this.y = y;this.owner = owner;}
	public Location(int x, int y, int owner, int score){this(x, y, owner);this.score = score;}
	public int getX(){return this.x;}//x 坐标
	public void setX(int x){this.x = x;}
	public int getY(){return this.y;} //y坐标
	public void setY(int y){this.y = y;}
	public int getOwner(){return this.owner;}// 棋盘点 状态坐标
	public void setOwner(int owner){this.owner = owner;}
	public int getScore(){return this.score;}// 该点分数
	public void setScore(int score){this.score = score;}
}
//下棋业务核心类,与界面棋盘对应,业务放在这里,可以和界面代码分离
 class Chess{
	public static final int CHESSBOARD_SIZE = 15;
	public static int FIRST = 1;//先手,-1表示机器,1表示人类,与Location类中的对应
	private int[][] chessboard = new int[CHESSBOARD_SIZE][CHESSBOARD_SIZE];//与界面棋盘对应,0代表空,-1代表机器,1代表人类
	private int[][] score = new int[CHESSBOARD_SIZE][CHESSBOARD_SIZE];//每个位置得分
	private int[] iswinxy=new int[6];//胜利棋子坐标。
	public Chess(){}	
	public void goback(int xy) {chessboard[xy/100][xy%100]=0;}
	public void init(){
		FIRST = 1;//默认人类先手
		for(int i = 0; i  < CHESSBOARD_SIZE; i++)
			for(int j = 0; j < CHESSBOARD_SIZE; j++){chessboard[i][j] = 0; score[i][j] = 0;}//初始化棋盘 和分数表
	}
	public void addChessman(int x, int y, int owner){chessboard[x][y] = owner;}	//落子
	public boolean isLegal(int x, int y){//棋盘边界判断 以及是否落子	//判断落子位置是否合法
		if(x >=0 && x < CHESSBOARD_SIZE && y >= 0 && y < CHESSBOARD_SIZE && chessboard[x][y] == 0)return true;
		return false;
	}
	public boolean isWin(int x, int y, int owner){//判断哪方赢了(必定有刚落的子引发,因此只需判断刚落子的周围),owner为-1代表机器,owner为1代表人类
	 int sum = 0,k=1; for(int i=0;i<6;i++)iswinxy[i]=0;
	 iswinxy[0]=x*100+y;
	 //判断纵向上下方向
	 for(int i = x - 1; i >= 0; i--)if(chessboard[i][y] == owner){ sum++;iswinxy[k++]=i*100+y;}else break;	
	 for(int i = x + 1; i < CHESSBOARD_SIZE; i++)if(chessboard[i][y] == owner){sum++;iswinxy[k++]=i*100+y;}else break;
     if(sum >= 4) {return true;}
	 //判断横向向左右边
     sum = 0;k=1;
	 for(int i = y - 1; i >= 0; i--)if(chessboard[x][i] == owner){sum++;iswinxy[k++]=x*100+i;}else break;
	 for(int i = y + 1; i < CHESSBOARD_SIZE; i++)if(chessboard[x][i] == owner){sum++;iswinxy[k++]=x*100+i;}else break;
	 if(sum >= 4) {return true;}
	 //判断左上角到右下角方向上侧和左上角到右下角方向下侧(正斜线)
	 sum = 0;k=1;
	 for(int i = x - 1, j = y - 1; i >= 0 && j >= 0; i--, j-- )if(chessboard[i][j] == owner){sum++;iswinxy[k++]=i*100+j;}else break;
	 for(int i = x + 1, j = y + 1; i < CHESSBOARD_SIZE && j < CHESSBOARD_SIZE; i++, j++ )if(chessboard[i][j] == owner){sum++;iswinxy[k++]=i*100+j;}else break;
	 if(sum >= 4) {return true;}
	 //判断右上角到左下角方向上侧和右上角到左下角方向下侧(反斜线)
	  sum = 0;k=1;
	  for(int i = x + 1, j = y - 1; i < CHESSBOARD_SIZE && j >= 0; i++, j--)if(chessboard[i][j] == owner){sum++;iswinxy[k++]=i*100+j;}else break;
	  for(int i = x - 1, j = y + 1; i >= 0 && j < CHESSBOARD_SIZE; i--, j++ )if(chessboard[i][j] == owner){sum++;iswinxy[k++]=i*100+j;}else break;
	  if(sum >= 4) {return true;}
       return false;
	}
	public int[] getisWinChess() { return iswinxy;}//获取胜利棋子
	public int[][] getchessborad() { return chessboard;}//获取胜利棋子
	//确定机器落子位置
	//使用五元贡献评分算法
	//算法思路:对15X15的572个五元组分别评分,一个五元组的得分就是该五元组为其中每个位置贡献的分数,  一个位置的分数就是其所在所有五元组分数之和。所有空位置中分数最高的那个位置就是落子位置。
	public Location searchLocation(){
		int humanChessmanNum = 0;//五元组中的黑棋数量
		int machineChessmanNum = 0;//五元组中的白棋数量
		int tupleScoreTmp = 0;//五元组得分临时变量
		int goalX = -1;//目标位置x坐标
		int goalY = -1;//目标位置y坐标	
		int maxScore = -1;//最大分数
		for(int i = 0; i  < CHESSBOARD_SIZE; i++)//每次都初始化下score评分数组(全部置零)每次机器找寻落子位置,评分都重新算一遍
		 for(int j = 0; j < CHESSBOARD_SIZE; j++) score[i][j] = 0;
		//1.扫描横向和横向的15个行
		for(int i = 0; i < CHESSBOARD_SIZE; i++){
			for(int j = 0; j < CHESSBOARD_SIZE-4; j++){
				for(int k = j; k < j + 5; k++)//每次加五个状态
					if(chessboard[i][k] == -1) machineChessmanNum++;else if(chessboard[i][k] == 1)humanChessmanNum++;
			  tupleScoreTmp = tupleScore(humanChessmanNum, machineChessmanNum);//为该五元组的每个位置添加分数
				for(int k = j; k < j + 5; k++)score[i][k] += tupleScoreTmp;
				humanChessmanNum =tupleScoreTmp=machineChessmanNum=0;//清零
				for(int k = j; k < j + 5; k++){//每次加五个状态
					if(chessboard[k][i] == -1) machineChessmanNum++;
					else if(chessboard[k][i] == 1)humanChessmanNum++;
				 }
			  tupleScoreTmp = tupleScore(humanChessmanNum, machineChessmanNum);
				for(int k = j; k < j + 5; k++)score[k][i] += tupleScoreTmp;
			   humanChessmanNum =tupleScoreTmp=machineChessmanNum=0;//清零
			}
		}
		//3.扫描右上角到左下角上侧部分
		for(int i = CHESSBOARD_SIZE-1; i >= 4; i--){
			for(int k = i, j = 0; j < CHESSBOARD_SIZE && k >= 0; j++, k--){
				int m = k, n = j;
				while(m > k - 5 && k - 5 >= -1){
					if(chessboard[m][n] == -1) machineChessmanNum++;
					else if(chessboard[m][n] == 1)humanChessmanNum++;
					m--;n++;
				}
				if(m == k-5){//注意斜向判断的时候,可能构不成五元组(靠近四个角落),遇到这种情况要忽略掉
					tupleScoreTmp = tupleScore(humanChessmanNum, machineChessmanNum);
					for(m = k, n = j; m > k - 5 ; m--, n++)score[m][n] += tupleScoreTmp;//为该五元组的每个位置添加分数
				}
				  humanChessmanNum =tupleScoreTmp=machineChessmanNum=0;//清零
			}
		}
		//4.扫描右上角到左下角下侧部分
		for(int i = 1; i < CHESSBOARD_SIZE; i++){
			for(int k = i, j = CHESSBOARD_SIZE-1; j >= 0 && k < CHESSBOARD_SIZE; j--, k++){
				int m = k,n=j;
				while(m < k + 5 && k + 5 <= CHESSBOARD_SIZE){
					if(chessboard[n][m] == -1) machineChessmanNum++;
					else if(chessboard[n][m] == 1)humanChessmanNum++;
					m++;n--;
				}
				if(m == k+5){//注意斜向判断的时候,可能构不成五元组(靠近四个角落),遇到这种情况要忽略掉
					tupleScoreTmp = tupleScore(humanChessmanNum, machineChessmanNum);
					for(m = k, n = j; m < k + 5; m++, n--)score[n][m] += tupleScoreTmp;//为该五元组的每个位置添加分数
				}
				humanChessmanNum =tupleScoreTmp=machineChessmanNum=0;//清零
			}
		}
		//5.扫描左上角到右下角部分
		for(int i = 0; i < CHESSBOARD_SIZE-4; i++){
			for(int k = i, j = 0; j < CHESSBOARD_SIZE && k < CHESSBOARD_SIZE; j++, k++){
				int m,n;
				for(m=k,n=j;m < k + 5 && k + 5 <= CHESSBOARD_SIZE;m++,n++){
					if(chessboard[m][n] == -1) machineChessmanNum++;
					else if(chessboard[m][n] == 1)humanChessmanNum++;
				}
				if(m == k + 5){//注意斜向判断的时候,可能构不成五元组(靠近四个角落),遇到这种情况要忽略掉
					tupleScoreTmp = tupleScore(humanChessmanNum, machineChessmanNum);
					for(m = k, n = j; m < k + 5; m++, n++)score[m][n] += tupleScoreTmp;	//为该五元组的每个位置添加分数
				}
				  humanChessmanNum =tupleScoreTmp=machineChessmanNum=0;//清零
			   for(m=k,n=j;m < k + 5 && k + 5 <= CHESSBOARD_SIZE;m++,n++){
						if(chessboard[n][m] == -1) machineChessmanNum++;
						else if(chessboard[n][m] == 1)humanChessmanNum++;
				}
				if(m == k + 5){//注意斜向判断的时候,可能构不成五元组(靠近四个角落),遇到这种情况要忽略掉
					tupleScoreTmp = tupleScore(humanChessmanNum, machineChessmanNum);
				   //为该五元组的每个位置添加分数
					for(m = k, n = j; m < k + 5; m++, n++)score[n][m] += tupleScoreTmp;
				 }
				humanChessmanNum =tupleScoreTmp=machineChessmanNum=0;//清零 
			}
		}		
		for(int i = 0; i < CHESSBOARD_SIZE; i++)//从空位置中找到得分最大的位置(确定落子位置)
			for(int j = 0; j < CHESSBOARD_SIZE; j++)
				if(chessboard[i][j] == 0 && score[i][j] > maxScore){goalX = i; goalY = j; maxScore = score[i][j];}
				else if(chessboard[i][j] != 0)score[i][j]=0;
		if(goalX != -1 && goalY != -1)return new Location(goalX, goalY, -1);
		return new Location(-1, -1, -1);//没找到坐标说明平局了
	}
	public int[][] getScores() {return score;}
	//各种五元组情况评分表
	public int tupleScore(int humanChessmanNum, int machineChessmanNum){
		int[] hb= {0,15,400,1800,100000};//人类落子 1,2,3,4 分别对应 15 400 1800,100000
		int[] mb= {0,35,800,15000,800000};//机器落子 1,2,3,4分别对应 35 800 15000 800000
		//1.既有人类落子,又有机器落子,判分为0
		if(humanChessmanNum > 0 && machineChessmanNum > 0)return 0;
		if(humanChessmanNum == 0 && machineChessmanNum == 0)return 7;
		if(machineChessmanNum >0)return mb[machineChessmanNum];
		if(humanChessmanNum>0)return hb[humanChessmanNum];
		return -1;//若是其他结果肯定出错了。这行代码根本不可能执行
	}
}
//自定义按钮
 class MyButton extends JButton  {
	 private Color quit = new Color(205, 255, 205);// 离开时颜色
	 public static final Color BUTTON_COLOR1 = new Color(205, 255, 205);
	 public static final Color BUTTON_COLOR2 = new Color(51, 154, 47);
	 public MyButton(String s) {
	  super(s);	
		setFont(new java.awt.Font(null,  1,  22)); //
		setBorder(BorderFactory.createRaisedBevelBorder());//凸出
		setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
	  setContentAreaFilled(false);// 是否显示外围矩形区域 选否
	 }
	 public void paintComponent(Graphics g) {
	  g.setColor(quit);
	  g.fillRoundRect(0, 0, getSize().width - 1, getSize().height - 1,20, 20);
	  super.paintComponent(g);
	 }
	 public void paintBorder(Graphics g) { g.drawRoundRect(0, 0, getSize().width - 1, getSize().height - 1,20, 20);}
 }

页面展示

1 主菜单页面展示

2 猜拳决定落子展示

3.下棋展示(当前落子圈红)

4.获胜突出现实展示

5.开启提示展示(绿色提示落子)

完整资源链接: 下载链接

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-06-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  •                        Java版五子棋小游戏(java控制台)
    • 前言: 该项目 为 Java 版五子棋小游戏,为控制台小游戏,主要功能有 人机大战,左右互战,可以悔棋可以提示,
      • 人机大战采用 五元贡献法,代码简单 实况效果好 ,相比 一般 博弈论 判断局面的方式,比正真的AI 还是有一定的差距。还有更多可扩展 可以自行摸索
        • 源码:https://github.com/Five-great/FiveChess
          • 页面展示
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档