日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

五子棋java判断平局_2020-10-03 Java初级项目——从零开始制作一个简易五子棋游戏...

發布時間:2025/5/22 java 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 五子棋java判断平局_2020-10-03 Java初级项目——从零开始制作一个简易五子棋游戏... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、棋盤的繪制

使用JFrame容器制作五子棋的窗體

創建一個類——UI,如下:

public class UI {

private JFrame frame = new JFrame();

public void init() {

frame.setTitle("五子棋");

frame.setSize(518, 540);

frame.setLocationRelativeTo(null); //居中

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.setVisible(true); //讓窗體顯示

}

public static void main(String[] args) {

new UI().init();

}

}

使用JPanel和Graphics畫出大小為15X15的棋盤

再創建一個新的類——Chessboard,繼承JPanel:

public class Chessboard extends JPanel {

//規定由15條橫豎線組成

private static final int CHESSBOARD_SIZE = 15;

//外邊距

private int margin = 20;

/**

* 繪圖工具

*

* @param g 畫筆工具

*/

@Override

public void paint(Graphics g) {

super.paint(g);

drawChessBoard(g);

drawPieces(g);

}

/**

* 畫棋盤

*

* @param g 畫筆工具

*/

private void drawChessBoard(Graphics g) {

int cellSize = (getWidth() - 2 * margin) / (CHESSBOARD_SIZE - 1);

for (int i = 0; i < CHESSBOARD_SIZE; i++) {

//畫橫線

g.drawLine(margin, margin + cellSize * i, getWidth() - margin, margin + cellSize * i);

//畫豎線

g.drawLine(margin + cellSize * i, margin, margin + cellSize * i, getHeight() - margin);

}

}

}

實現點擊鼠標落子的功能

在UI類中添加以下代碼:

public class UI {

private JFrame frame = new JFrame();

private Chessboard chessboard = new Chessboard();

public void init() {

frame.setTitle("五子棋");

frame.setSize(518, 540);

frame.setLocationRelativeTo(null); //居中

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.setVisible(true); //讓窗體顯示

//給棋盤添加鼠標監聽事件,具體來說就是鼠標點擊事件

chessboard.addMouseListener(new MouseAdapter() { //匿名內部類

@Override

public void mouseClicked(MouseEvent e) {

super.mouseClicked(e);

//調用畫棋子的方法

play(e);

}

});

}

/**

* 處理鼠標點擊事件的方法

*/

private void play(MouseEvent e) {

int cellSize = chessboard.getCellSize();

int x = (e.getX() - 5) / cellSize;

int y = (e.getY() - 5) / cellSize;

chessboard.move(new Pieces(x, y, 1));

}

public static void main(String[] args) {

new UI().init();

}

}

再在Chessboard類中添加drawPieces、move、getCellSize方法,如下:

public class Chessboard extends JPanel {

private List piecesList = new ArrayList<>();

/**

* 繪圖工具

*

* @param g 畫筆工具

*/

@Override

public void paint(Graphics g) {

super.paint(g);

drawChessBoard(g);

drawPieces(g);

}

public int getCellSize() {

return (getWidth() - 2 * margin) / (CHESSBOARD_SIZE - 1);

}

public void drawPieces(Graphics g) {

for (Pieces piece : piecesList) {

if (piece.getPlayer() == 1) {

//默認值為1代表人類,棋子顏色為黑色

g.setColor(Color.black);

} else {

g.setColor(Color.white);

}

int cellSize = (getWidth() - 2 * margin) / (CHESSBOARD_SIZE - 1);

g.fillOval(piece.getX() * cellSize + margin - cellSize / 2, piece.getY() * cellSize + margin - cellSize / 2, cellSize, cellSize);

}

}

/**

* 落子的方法

*/

public void move(Pieces piece) {

piecesList.add(piece);

repaint();

}

}

然后創建一個新的類——Pieces,如下:

/***

* 棋子對象

*/

public class Pieces {

private int x;

private int y;

private int player; //表示黑棋還是白棋,1代表黑棋,-1代表白棋

public Pieces(int x, int y, int player) {

this.x = x; //非實際坐標,而是格子數,第x格

this.y = y; //同上,第y格

this.player = player;

}

public int getX() {

return x;

}

public int getY() {

return y;

}

public int getPlayer() {

return player;

}

}

二、判斷勝負

實現五子棋勝負判斷的思路是:

判斷勝負就看哪個顏色的棋子首先達到五子相連。若黑棋先達到五子相連,則黑棋勝,否則,白棋勝;

也就是下在每個棋子時都要判斷它的八個方向的棋子相連個數,如果判斷某一方向與其相鄰點的顏色相同,將循環計數;

還需要注意邊界點的范圍,在循環的時候應注意設置邊界條件;

可以建一個類,在類中寫判斷輸贏的方法;

在Chessboard類中添加如下代碼:

public class Chessboard extends JPanel {

private static final int CHESSBOARD_SIZE = 15;

private int margin = 20;

private List piecesList = new ArrayList<>();

//創建一個數組,用來表示棋盤上被占用的位置

private int[][] location = new int[CHESSBOARD_SIZE][CHESSBOARD_SIZE];

}

但是,落子的位置是有限制的,具體來說就是:

落子的位置不能有其它棋子;

不能超過棋盤的邊界;

所以要在UI類中的play()方法里添加一個落子合法性的判定:

private void play(MouseEvent e) {

int cellSize = chessboard.getCellSize();

int x = (e.getX() - 5) / cellSize;

int y = (e.getY() - 5) / cellSize;

if (chessboard.isLegal(x, y)) {

//添加棋子

chessboard.move(new Pieces(x, y, 1));

//記錄人類落子的位置

chessboard.setLocation(x, y, 1);

//判斷輸贏

if (chessboard.checkWinner(x, y, 1)) {

JOptionPane.showMessageDialog(frame, "人類獲勝", "您贏了!", JOptionPane.PLAIN_MESSAGE);

return;

}

}

}

而對應Chessboard類中新增的isLegal方法、setLocation方法以及checkWinner方法就是:

/**

* 判斷是否重復落子以及落子位置是否合法

*/

public boolean isLegal(int x, int y) {

return x >= 0 && x <= CHESSBOARD_SIZE && y >= 0 && y <= CHESSBOARD_SIZE && location[x][y] == 0;

}

/**

* 記錄落子后,棋子占用棋盤的位置

*/

public void setLocation(int x, int y, int player) {

location[x][y] = player;

}

/**

* 判斷勝負

*/

public boolean checkWinner(int x, int y, int player) {

int sum = 0;

//判斷水平方向,水平左側

for (int i = x - 1; i >= 0; i--) {

if (location[i][y] == player) {

sum++;

} else {

break;

}

}

//水平右側

for (int i = x + 1; i <= CHESSBOARD_SIZE; i++) {

if (location[i][y] == player) {

sum++;

} else {

break;

}

}

if (sum >= 4) {

return true;

}

//判斷垂直方向

sum = 0;

for (int i = y - 1; i >= 0; i--) {

if (location[x][i] == player) {

sum++;

} else {

break;

}

}

for (int i = y + 1; i <= CHESSBOARD_SIZE; i++) {

if (location[x][i] == player) {

sum++;

} else {

break;

}

}

if (sum >= 4) {

return true;

}

//判斷左上到右下這個對角線方向

sum = 0;

for (int i = x - 1, j = y - 1; i >= 0 && j >= 0; i--, j--) {

if (location[i][j] == player) {

sum++;

} else {

break;

}

}

for (int i = x + 1, j = y + 1; i <= CHESSBOARD_SIZE && j <= CHESSBOARD_SIZE; i++, j++) {

if (location[i][j] == player) {

sum++;

} else {

break;

}

}

if (sum >= 4) {

return true;

}

//判斷右上到左下這個對角線方向

sum = 0;

for (int i = x + 1, j = y - 1; i <= CHESSBOARD_SIZE && j >= 0; i++, j--) {

if (location[i][j] == player) {

sum++;

} else {

break;

}

}

for (int i = x - 1, j = y + 1; i >= 0 && j <= CHESSBOARD_SIZE; i--, j++) {

if (location[i][j] == player) {

sum++;

} else {

break;

}

}

if (sum >= 4) {

return true;

}

sum = 0;

return false;

}

三、簡易的AI算法

思路:

五元組:棋盤中橫豎斜四個方向的所有相鄰五個可連成一條線的格子

五元組的表示:用某格子的橫縱坐標以及+1/-1來表示相鄰四個格子的坐標,從而計算五元組坐標

五子棋棋盤大小是15X15,橫豎斜四個方向共有572個五元組,給每個五元組一個評分

這個五元組將為它的每個位置貢獻的分數就是這個五元組自身的得分

對整個棋盤來說,每個位置的得分就是該位置所在的橫豎斜四個方向所有五元組的得分之和

然后從所有空位置中選得分最高的位置即為機器落子的位置

首先,添加機器落子的代碼,完善UI類中play方法:

private void play(MouseEvent e) {

int cellSize = chessboard.getCellSize();

int x = (e.getX() - 5) / cellSize;

int y = (e.getY() - 5) / cellSize;

if (chessboard.isLegal(x, y)) {

//添加棋子

chessboard.move(new Pieces(x, y, 1));

//記錄人類落子的位置

chessboard.setLocation(x, y, 1);

//判斷輸贏

if (chessboard.checkWinner(x, y, 1)) {

JOptionPane.showMessageDialog(frame, "人類獲勝", "您贏了!", JOptionPane.PLAIN_MESSAGE);

return;

}

//機器落子

Pieces piece = chessboard.searchLocation();

chessboard.move(piece);

chessboard.setLocation(piece.getX(),piece.getY(),piece.getPlayer());

//判斷勝負

if (chessboard.checkWinner(piece.getX(),piece.getY(),piece.getPlayer())){

JOptionPane.showMessageDialog(frame, "電腦獲勝", "您輸了!", JOptionPane.PLAIN_MESSAGE);

}

}

}

其次,還需要一個評估函數(評分表),來對整個棋局中有效位置進行評價,但評分表很難確定,沒有所謂最好的,只能根據經驗和測試來選擇,我選擇的評分表如下:

既有人類落子,又有機器落子,判分為0;

全部為空,沒有落子,判分為7;

機器落1子,判分為35

機器落2子,判分為800

機器落3子,判分為15000

機器落4子,評分為800000

人類落1子,評分為15

人類落2子,評分為400

人類落3子,評分為1800

人類落4子,評分為100000

在Chessboard類中添加tupleScore方法:

private int tupleScore(int humanChessmanNum, int machineChessmanNum) {

if (humanChessmanNum > 0 && machineChessmanNum > 0) {

return 0;

}

if (humanChessmanNum == 0 && machineChessmanNum == 0) {

return 7;

}

if (machineChessmanNum == 1) {

return 35;

}

if (machineChessmanNum == 2) {

return 800;

}

if (machineChessmanNum == 3) {

return 15000;

}

if (machineChessmanNum == 4) {

return 800000;

}

if (humanChessmanNum == 1) {

return 15;

}

if (humanChessmanNum == 2) {

return 400;

}

if (humanChessmanNum == 3) {

return 1800;

}

if (humanChessmanNum == 4) {

return 100000;

}

return -1;

}

在Chessboard類中添加searchLocation方法:

/**

* 計算機器落子的最佳位置

*/

public Pieces searchLocation() {

//每次都初始化一下score的評分數組

for (int i = 0; i < CHESSBOARD_SIZE; i++) {

for (int j = 0; j < CHESSBOARD_SIZE; j++) {

score[i][j] = 0;

}

}

//每次機器尋找了落子位置,評分都重新計算一遍

int humanChessmanNum = 0;

int machineChessmanNum = 0;

int tupleScoreTmp = 0;

int goalX = -1;

int goalY = -1;

int maxScore = -1;

//縱向掃描棋盤

for (int i = 0; i < 15; i++) {

for (int j = 0; j < 11; j++) {

int k = j;

while (k < j + 5) {

if (location[j][k] == -1) machineChessmanNum++;

else if (location[i][k] == 1) humanChessmanNum++;

k++;

}

// 將每一個五元組中的黑棋個數與白棋個數傳入評分表中

tupleScoreTmp = tupleScore(humanChessmanNum, machineChessmanNum);

//為該五元組的每一個位置添加分數

for (k = j; k < j + 5; k++) {

score[i][k] += tupleScoreTmp;

}

//歸零

humanChessmanNum = 0;

machineChessmanNum = 0;

tupleScoreTmp = 0;

}

}

//橫向掃描棋盤

for (int i = 0; i < 15; i++) {

for (int j = 0; j < 11; j++) {

int k = j;

while (k < j + 5) {

if (location[k][i] == -1) machineChessmanNum++;

else if (location[k][i] == 1) humanChessmanNum++;

k++;

}

// 將每一個五元組中的黑棋個數與白棋個數傳入評分表中

tupleScoreTmp = tupleScore(humanChessmanNum, machineChessmanNum);

//為該五元組的每一個位置添加分數

for (k = j; k < j + 5; k++) {

score[k][i] += tupleScoreTmp;

}

//歸零

humanChessmanNum = 0;

machineChessmanNum = 0;

tupleScoreTmp = 0;

}

}

//3.掃描右對角線 上側部分

for (int i = 14; i >= 4; i--) {

for (int k = i, j = 0; j < 15 && k >= 0; j++, k--) {

int m = k; //x軸

int n = j; //y軸

while (m > k - 5 && k - 5 >= -1) {

if (location[m][n] == -1) machineChessmanNum++;

else if (location[m][n] == 1) humanChessmanNum++;

m--;

n++;

}

//注意斜向判斷時,可能不構成五元組(靠近四個角落),遇到這種情況要忽略掉

if (m == k - 5) {

tupleScoreTmp = tupleScore(machineChessmanNum, humanChessmanNum);

for (m = k, n = j; m > k - 5; m--, n++) {

score[m][n] += tupleScoreTmp;

}

}

//歸零

humanChessmanNum = 0;

machineChessmanNum = 0;

tupleScoreTmp = 0;

}

}

//4.掃描右對角線 下側部分

for (int i = 1; i < 15; i++) {

for (int k = i, j = 14; j >= 0 && k < 15; j--, k++) {

int m = k;

int n = j;

while (m < k + 5 && k + 5 <= 15) {

if (location[n][m] == -1) machineChessmanNum++;

else if (location[n][m] == 1) humanChessmanNum++;

m++;

n--;

}

if (m == k + 5) {

tupleScoreTmp = tupleScore(machineChessmanNum, humanChessmanNum);

for (m = k, n = j; m < k + 5; m++, n--) {

score[n][m] += tupleScoreTmp;

}

}

//歸零

humanChessmanNum = 0;

machineChessmanNum = 0;

tupleScoreTmp = 0;

}

}

//5.掃描左對角線上側部分

for (int i = 0; i < 11; i++) {

for (int k = i, j = 0; j < 15 && k < 15; j++, k++) {

int m = k;

int n = j;

while (m < k + 5 && k + 5 <= 15) {

if (location[m][n] == -1) machineChessmanNum++;

else if (location[m][n] == 1) humanChessmanNum++;

m++;

n++;

}

if (m == k + 5) {

tupleScoreTmp = tupleScore(machineChessmanNum, humanChessmanNum);

for (m = k, n = j; m < k + 5; m++, n++) {

score[m][n] += tupleScoreTmp;

}

}

//歸零

humanChessmanNum = 0;

machineChessmanNum = 0;

tupleScoreTmp = 0;

}

}

//6.掃描左對角線下側部分

for (int i = 1; i < 11; i++) {

for (int k = i, j = 0; j < 15 && k < 15; j++, k++) {

int m = k;

int n = j;

while (m < k + 5 && k + 5 <= 15) {

if (location[n][m] == -1) machineChessmanNum++;

else if (location[n][m] == 1) humanChessmanNum++;

m++;

n++;

}

if (m == k + 5) {

tupleScoreTmp = tupleScore(machineChessmanNum, humanChessmanNum);

for (m = k, n = j; m < k + 5; m++, n++) {

score[n][m] += tupleScoreTmp;

}

}

//歸零

humanChessmanNum = 0;

machineChessmanNum = 0;

tupleScoreTmp = 0;

}

}

//從空位置中找到最大的位置

for (int i = 0; i < 15; i++) {

for (int j = 0; j < 15; j++) {

if (location[i][j] == 0 && score[i][j] > maxScore) {

goalX = i;

goalY = j;

maxScore = score[i][j];

}

}

}

if (goalX != -1) {

return new Pieces(goalX, goalY, -1);

}

//沒找到坐標說明平局,暫不處理

return new Pieces(-1, -1, -1);

}

(完)

《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的五子棋java判断平局_2020-10-03 Java初级项目——从零开始制作一个简易五子棋游戏...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产系列在线 | 日韩欧美国产电影 | 一级片在线免费播放 | 国产午夜福利精品 | 国产乱妇4p交换乱免费视频 | 欧美日韩中文字幕一区二区 | 国产第一页在线播放 | 特级丰满少妇一级aaaa爱毛片 | 亚洲中文字幕无码一区二区三区 | 国产精品无码中文 | 亚洲福利专区 | www国产91 | 2021国产在线视频 | 久久精品午夜 | 网站在线播放 | 麻豆三级在线观看 | 人妻互换免费中文字幕 | 午夜剧场免费看 | 成人妇女淫片aaaa视频 | 一区二区欧美视频 | 丰满岳妇伦在线播放 | 高清国产午夜精品久久久久久 | 伊人久久青青 | 激情小说激情视频 | 亚洲人精品 | 国产免费脚交足视频在线观看 | 欧美亚洲第一页 | 久久大陆 | 欧美乱妇在线观看 | 日韩一区二区三区三四区视频在线观看 | 国产又粗又猛又爽又黄又 | 色一情一区二区三区四区 | 懂色av懂色av粉嫩av分享吧 | 国产亚洲欧美日韩高清 | 久久久精品视频在线观看 | 上原亚衣在线观看 | 乳孔很大能进去的av番号 | 国产一级做a爱片久久毛片a | 欧美在线一区二区三区四区 | 深田咏美中文字幕 | 久久久免费高清视频 | 亚洲涩视频 | 午夜精品久久久久久久蜜桃 | 国产一区久久久 | 午夜毛片 | 日韩一区二区精品 | 国产国语老龄妇女a片 | 全国最大色| 日本在线观看一区 | 日日夜夜免费精品视频 | 国产综合精品久久久久成人影 | 美女隐私黄www网站动漫 | 日韩在线精品视频一区二区涩爱 | 国产精品ⅴa有声小说 | 国产一线二线三线女 | 91九色高潮 | 免费大片黄在线观看视频网站 | 99激情视频 | 天堂网在线资源 | 久久午夜精品人妻一区二区三区 | 免费在线观看毛片视频 | 亚色视频 | 中文字幕第页 | 成人精品自拍 | 国产一区二区视频免费 | 毛片基地免费观看 | 大肉大捧一进一出好爽 | 蜜桃又黄又粗又爽av免 | 呦呦色 | 午夜极品视频 | 免费污片软件 | 久久99免费视频 | 成人午夜在线视频 | 亚洲视频黄 | 99ri国产| 成人91| 黄色一级网址 | 国产浮力影院 | 国产一区精品在线观看 | 国产色呦呦 | 亚洲经典一区 | 少妇人妻偷人精品视频蜜桃 | 手机看片在线观看 | 亚洲成年人网站在线观看 | 亚洲成人福利在线 | 网站av在线 | 欧美人体做爰大胆视频 | av手机在线观看 | 女性爱爱视频 | 国产精品高潮呻吟久久 | a级黄片毛片 | 91破处视频 | 免费欧美一级片 | 人成精品 | 成人免费视频网站 | 国产成人av一区二区三区在线观看 | 成人午夜激情影院 | 无码内射中文字幕岛国片 | 国产精品久久久久av |