**
这个是自己从 网上找的关于五子棋的代码只用于自己提高阅读代码的能力 不做任何商业用途 (稍后更新打包成exe的过程)
这个是打开后的页面
代码片
// An highlighted block
public static void main(String[] args) {
EventQueue.invokeLater(() ->{
JFrame frame=new MyFiveChessFrame(new StupidRobot());
frame.setTitle("五子棋");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setVisible(true);
/**
* () ->{} java8的lambda表达式 可以自己去百度 本人也是小白 自己搜索的
*/
});
}
public interface IRobot {
static final Random rand = new Random();
default Pair getDeterminedPos() {
return new Pair(rand.nextInt(15) + 1, rand.nextInt(15) + 1);
}
void retrieveGameBoard(int[][] gameBoard);
}
class MyFiveChessFrame extends JFrame
{
public MyFiveChessFrame(IRobot robot)
{
add(new ImageComponent(robot));
pack();
}
}
/**
* A component that displays a tiled image
*/
class ImageComponent extends JComponent implements MouseListener
{
private static final int DEFAULT_WIDTH = 500;//因为图片的大小为500*500,
private static final int DEFAULT_HEIGHT = 500;//所以这里设置组件大小也为500*500
int x; //原图是没有棋盘的,这里我们要自己画
int y; //棋盘,故需要全局变量来获取棋盘坐标
int allchess[][] = new int[16][16]; //构造一个数组来存取当前局势情况
boolean isBlack = true; //0代表没有棋,1代表黑子,2代表白子
boolean canPlay = true;//isBlack是用来说明当前应该是黑子或者白子落棋
private Image image; //canPlay是用来设置当游戏结束后不能够再落子
private IRobot iRobot; //用来存储传入构造器的iRobot
private String string = "It's Black"; //图片上当前会显示该黑子落棋
public ImageComponent(IRobot iRobot)
{
this.iRobot = iRobot;
addMouseListener(this); //要实现当点击鼠标就发生响应就必须实现MouseListener接口
image = new ImageIcon("background.jpg").getImage();
} //背景图在最下面会贴出来的
public void paint(Graphics g) //构造paint方法
{
if (image == null) return;
g.drawImage(image, 0, 0, null);
g.setFont(new Font("宋体", 0, 16));
g.setFont(new Font("Times New Roman", 0, 27));
g.drawString(string, 135, 34);
for (int i = 0; i < 16; i++) {//这里是在画棋盘(国际棋盘大小15*15)
g.drawLine(10, 50 + i*24, 369, 50 + i*24);
g.drawLine(10 + i*24, 50, 10 + i*24, 410);
}
for (int i = 0; i < 16; i++) {
for(int j = 0; j < 16; j++)
{
if(allchess[i][j] == 1) {//为1时是黑子,这里需要调用fillOval方法画圆
int tempx = i * 24 + 10;
int tempy = j * 24 + 50;
g.fillOval(tempx-7, tempy-7, 14, 14);
}
if (allchess[i][j] == 2) {//当白子的时候需要画一个白色的圆再添加一个黑色的框
int tempx = i * 24 + 10;
int tempy = j * 24 + 50;
g.setColor(Color.WHITE);
g.fillOval(tempx-7, tempy-7, 14, 14);
g.setColor(Color.BLACK);
g.drawOval(tempx-7, tempy-7, 14, 14);
}
}
}
}
public Dimension getPreferredSize() { return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT); }
@SuppressWarnings("deprecation")
@Override
public void mouseClicked(MouseEvent e) {//下面就是实现游戏界面右边的几个功能
// TODO Auto-generated method stub
if (x>400 && x<470 && y>50 && y<80) {
int restart = JOptionPane.showConfirmDialog(this, "是否确认重新开始游戏");
if (restart == 0) {
allchess = new int[16][16];
string = "It's Black";
isBlack = true;
this.repaint();
}
}
if (x>400 && x<470 && y>100 && y<130) {
String input = JOptionPane.showInputDialog("请输入最大下棋时间(单位分),0代表无限制:");//这部分功能没有实现,本来是想用线程来实现一个游戏倒计时功能的,但是因为某些原因就放弃了
}
if (x>400 && x<470 && y>150 && y<180) {
JOptionPane.showMessageDialog(this, "五子棋你都不会下么,如果不会,请参见百度,谢谢!");
}
if (x>400 && x<470 && y>250 && y<280) {
int abandoning = JOptionPane.showConfirmDialog(this, "已经决定了么");
if (abandoning == 0) {
if(isBlack) JOptionPane.showMessageDialog(this, "黑方认输");
canPlay = false;
System.exit(0);
}
}
if (x>400 && x<470 && y>300 && y<330) {
JOptionPane.showMessageDialog(this, "本软件由杨易大佬与曾鑫开发,若有问题,请自行解决.");
}
if (x>400 && x<470 && y>350 && y<380) {
int Continue = JOptionPane.showConfirmDialog(this, "不再玩一会么");
if(Continue == 0) {
JOptionPane.showMessageDialog(this, "大爷再见,欢迎下次再来。");
System.exit(0);
}
}
}
@Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
//System.out.println("X" + e.getX());//在划线之前要确认坐标,需要输出坐标
//System.out.println("Y" + e.getY());
if (canPlay == true) {
x = e.getX();
y = e.getY();
if (x>10 && x<369 && y>49 && y<408) {
float xxx = (float) 24.0;
x = Math.round((x - 10)/xxx);//实现坐标的4舍5入
y = Math.round((y - 49)/xxx);
if(allchess[x][y] == 0)
{
if (isBlack == true) {
allchess[x][y] = 1;
iRobot.retrieveGameBoard(allchess);//该机器人下棋时,需要将现在棋盘的局势传递过去
isBlack = false;
string = "It's White";
boolean winFlag = this.checkWin();//每下一次棋时都需要检查是否胜出
if (winFlag == true) {
JOptionPane.showMessageDialog(this, "Game over"+(allchess[x][y]==1 ? "Black" : "White") + "winned");
canPlay = false;
}
RobotAction();//机器人下棋
this.repaint();
}
}
else {
JOptionPane.showMessageDialog(this, "Please play chess in the chessboard");
}
}
}
}
void RobotAction(){
Pair pair = iRobot.getDeterminedPos();//机器人类将返回一个pair类回来
x = pair.x;
y= pair.y;
allchess[x][y] = 2;
isBlack = true;
string = "It's Black";
boolean winFlag = this.checkWin();
if (winFlag == true) {
JOptionPane.showMessageDialog(this, "Game over"+(allchess[x][y]==1 ? "Black" : "White") + " winned");
canPlay = false;
}
}
@Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
private boolean checkWin() {//检测当前是否由五子连线的方法,简述一下,这个方法其实很简单,只要我们在每一次落子的时候检查是否由五子连线就可以确保一旦有人胜出,我们就可以马上发现。先检查横线和竖线,再检查左右斜线。
boolean flag = false; //设置的标志,当由五子连线时就返回flag=false
int count = 1; //计数当前由几颗棋子相连
int color = allchess[x][y];
int i = 1;
while(((x+i)<16)&&color == allchess[x+i][y]) {
count++;
i++;
}
i = 1;
while(((x-i)>=1)&&color == allchess[x-i][y]) {
count++;
i++;
}
if(count>=5)
{flag = true;}
//?????ж?
int count2 = 1;
int i2 = 1;
while(((y+i2)<16)&&color == allchess[x][y+i2]) {
count2++;
i2++;
}
i = 1;
while(((y-i2)>=1)&&color == allchess[x][y-i2]) {
count2++;
i2++;
}
if(count2>=5)
{flag = true;}
int count3 = 1;
int i3 = 1;
while(((y-i3)>=1)&&((x+i3)<16)&&color == allchess[x+i3][y-i3]) {
count3++;
i3++;
}
i = 1;
while(((x-i3)>=1)&&((y+i3)<16)&&color == allchess[x-i3][y+i3]) {
count3++;
i3++;
}
if(count3>=5)
{flag = true;}
int count4 = 1;
int i4 = 1;
while(((y-i4)>=1)&&((x-i4)>=1)&&color == allchess[x-i4][y-i4]) {
count4++;
i4++;
}
i = 1;
while(((x+i4)<16)&&((y+i4)<16)&&color == allchess[x+i4][y+i4]) {
count4++;
i4++;
}
if(count4>=5)
{flag = true;}
return flag;
}
public class Pair {
public int x;
public int y;
public Pair(){}
public Pair(int x, int y) {
this.x = x;
this.y = y;
}
}
public class StupidRobot implements IRobot {
private static final int BOARD_SIZE = 15;
private static final int ROLE_OPPONENT = 1;
private static final int ROLE_ROBOT = 2;
private static final int ROLE_NON = 0;
private static final int ORIENTATION_LR = 0;
private static final int ORIENTATION_UD = 1;
private static final int ORIENTATION_LT_RD = 2;
private static final int ORIENTATION_RT_LD = 3;
private int[][] boardRef = null;
/**
* There we provide a default implementation to simulate robot's behavior
*
* @return a {@code robot.Pair} which contains a valid (x,y) position
*/
@Override
public Pair getDeterminedPos() {
int[][] situationRobot = new int[boardRef.length][boardRef[0].length];
int[][] situationOpponent = new int[boardRef.length][boardRef[0].length];
int maxRobotScore = 0;
Pair maxRobotPoint = new Pair();
int maxOpponentScore = 0;
Pair maxOpponentPoint = new Pair();
for(int i=0;i<BOARD_SIZE;i++){
for(int k=0;k<BOARD_SIZE;k++){
if(boardRef[i][k]!=ROLE_NON){
situationOpponent[i][k]=situationRobot[i][k]=0;
}else{
boardRef[i][k] = ROLE_OPPONENT;
situationOpponent[i][k] = evaluateScore(ROLE_OPPONENT,i,k);
boardRef[i][k]=ROLE_NON;
if(situationOpponent[i][k]>maxOpponentScore){
maxOpponentScore = situationOpponent[i][k];
maxOpponentPoint.x = i;
maxOpponentPoint.y = k;
}
boardRef[i][k]=ROLE_ROBOT;
situationRobot[i][k]=evaluateScore(ROLE_ROBOT,i,k);
boardRef[i][k]=ROLE_NON;
if(situationRobot[i][k]>maxRobotScore){
maxRobotScore = situationRobot[i][k];
maxRobotPoint.x = i;
maxRobotPoint.y = k;
}
}
}
}
if(maxRobotScore > maxOpponentScore || maxRobotScore==Integer.MAX_VALUE){
return maxRobotPoint;
}else{
return maxOpponentPoint;
}
}
/**
* This method is used to retrieve game board such that robot can determine its (x,y) position
*
* @param gameBoard the 2-dimension array to represent the game board
*/
@Override
public void retrieveGameBoard(int[][] gameBoard) {
boardRef = gameBoard;
}
/**
* The policy of evaluating was referred to https://www.cnblogs.com/maxuewei2/p/4825520.html
* @param role the role of current player
* @param x position x
* @param y position y
* @param orientation orientation of determining line
* @return
*/
private int patternRecognition(int role, int x,int y,int orientation){
StringBuilder sb = new StringBuilder();
if(orientation==ORIENTATION_LR){
int leftBound = (x - 4)>=0?x-4:0;
int rightBound = (x +4)<BOARD_SIZE?x+4:BOARD_SIZE-1;
for(int i=leftBound;i<=rightBound;i++){
sb.append(boardRef[i][y]);
}
}else if(orientation == ORIENTATION_UD){
int bottomBound = (y+4)<BOARD_SIZE?y+4:BOARD_SIZE-1;
int topBound = (y-4)>=0?y-4:0;
for(int i=topBound;i<=bottomBound;i++){
sb.append(boardRef[x][i]);
}
}else if(orientation== ORIENTATION_LT_RD){
int leftBound = 0,rightBound = 0,bottomBound = 0,topBound = 0;
for(int i=1;i<=4;i++){
leftBound = x-i;
topBound = y-i;
if(leftBound<0||topBound<0){
leftBound++;
topBound++;
break;
}
}
for(int k=1;k<=4;k++){
rightBound = x+k;
bottomBound = y+k;
if(rightBound>BOARD_SIZE||bottomBound>BOARD_SIZE){
rightBound--;
bottomBound--;
break;
}
}
for(int i=topBound,k=leftBound;i<=bottomBound && k<=rightBound;i++,k++){
sb.append(boardRef[k][i]);
}
}else if(orientation== ORIENTATION_RT_LD){
int leftBound = 0,rightBound = 0,bottomBound = 0,topBound = 0;
for(int i=1;i<=4;i++){
rightBound = x+i;
topBound = y-i;
if(rightBound>BOARD_SIZE||topBound<0){
rightBound--;
topBound++;
break;
}
}
for(int k=1;k<=4;k++){
leftBound = x-k;
bottomBound = y+k;
if(leftBound<0||bottomBound>BOARD_SIZE){
leftBound++;
bottomBound--;
break;
}
}
for(int i=topBound,k=rightBound;i<=bottomBound && k>=leftBound;i++,k--){
sb.append(boardRef[k][i]);
}
}
String str = sb.toString();
if(str.contains(role == ROLE_ROBOT ? "22222" : "11111")){
return Integer.MAX_VALUE;
}
if(str.contains(role == ROLE_ROBOT ? "022220" : "011110")){
return 300000;
}
if(str.contains(role == ROLE_ROBOT ? "22202" : "11101") ||
str.contains(role == ROLE_ROBOT ? "20222" : "10111")){
return 3000;
}
if(str.contains(role == ROLE_ROBOT ? "0022200" : "0011100")){
return 3000;
}
if(str.contains(role == ROLE_ROBOT ? "22022" : "11011")){
return 2600;
}
if(str.contains(role == ROLE_ROBOT ? "22220" : "11110")||
str.contains(role == ROLE_ROBOT ? "02222" : "01111")){
return 2500;
}
if(str.contains(role == ROLE_ROBOT ? "020220" : "010110")||
str.contains(role == ROLE_ROBOT ? "022020" : "011010")){
return 800;
}
if(str.contains(role == ROLE_ROBOT ? "00022000" : "00011000")){
return 650;
}
if(str.contains(role == ROLE_ROBOT ? "20022" : "10011")||
str.contains(role == ROLE_ROBOT ? "22002" : "11001")){
return 600;
}
if(str.contains(role == ROLE_ROBOT ? "20202" : "10101")){
return 550;
}
if(str.contains(role == ROLE_ROBOT ? "22200" : "11100")||
str.contains(role == ROLE_ROBOT ? "00222" : "00111")){
return 500;
}
if(str.contains(role == ROLE_ROBOT ? "0020200" : "0010100")){
return 250;
}
if(str.contains(role == ROLE_ROBOT ? "020020" : "010010")){
return 200;
}
if(str.contains(role == ROLE_ROBOT ? "22000" : "11000")||
str.contains(role == ROLE_ROBOT ? "00022" : "00011")){
return 150;
}
return 0;
}
private int evaluateScore(int role,int x, int y){
int a = patternRecognition(role,x,y,ORIENTATION_RT_LD);
int b = patternRecognition(role,x,y,ORIENTATION_LT_RD);
int c = patternRecognition(role,x,y,ORIENTATION_UD);
int d = patternRecognition(role,x,y,ORIENTATION_LR);
return Math.max(Math.max(Math.max(a,b),c),d);
}
}