基於Java Swing五子棋小遊戲設計和實現
前言:
五子棋相傳起源於四千多年前的堯帝時期,比圍棋的歷史還要悠久,可能早在“堯造圍棋”之前,民間就已有五子棋遊戲。有關早期五子棋的文史資料與圍棋有相似之處,因為古代五子棋的棋具與圍棋是完全相同的。 在上古的神話傳說中有“女媧造人, 伏羲做棋”一說,《增山海經》中記載: “休輿之山有石焉, 名曰帝臺之棋, 五色而文狀鶉卵。 ”善注引三國淳《藝經》 中曰: “棋局,縱橫各十七道,合二百八十九道,白黑棋子,各一百五十枚”。這段雖沒明講是何種棋類,但至少知道遠古就以漂亮的石頭為棋子。因而規則簡單的五子棋也可能出自當時,並是用石子作棋子。亦有傳說,五子棋最初流行於少數民族地區,以後漸漸演變成圍棋並在炎黃子後代中遍及開來。
專案結構:
功能截圖:
關鍵程式碼:
初始化引數:
private ImageIcon map; //棋盤背景點陣圖
private ImageIcon blackchess; //黑子點陣圖
private ImageIcon whitechess; //白子點陣圖
public int isChessOn [][]; //棋局
protected boolean win = false; // 是否已經分出勝負
protected int win_bw; // 勝利棋色
protected int deep = 3, weight = 7; // 搜尋的深度以及廣度
public int drawn_num = 110; // 和棋步數
int chess_num = 0; // 總落子數目
public int[][] pre = new int[drawn_num + 1][2]; // 記錄下棋點的x,y座標 最多 (drawn_num + 1) 個
public int sbw = 0; //玩家棋色黑色0,白色1
public int bw = 0; // 當前應該下的棋色 0:黑色(預設), 1:白色
// 邊界值,用於速度最佳化
protected int x_max = 15, x_min = 0;
protected int y_max = 15, y_min = 0;
protected boolean able_flag = true; // 是否選擇禁手標誌 0:無禁手 1:有禁手(預設
private int h; //棋子長
private int w; //棋子寬
private int insx; //插入棋子的位置
private int insy;
private Point mousePoint; //滑鼠當前位置
private int winer; //獲勝方
private boolean humanhuman=false; //是否是人人對弈
private int plast=0; //走了幾步了,
public int BLACK_ONE; //0表黑子
public int WHITE_ONE; //1表白子
public int NONE_ONE; //2表無子
public int N; //棋盤邊長
電腦下棋邏輯處理:
public void putOne(int bwf ) { //bwf 棋色 0:黑色 1:白色
int x, y, mx = -100000000;
x = y = -1;
// 搜尋最優下棋點
int[][] bests = getBests( bwf );
for (int k = 0; k < bests。length; k++) {
int i = bests[k][0];
int j = bests[k][1];
// 有成5,則直接下子,並退出迴圈。。沒有,則思考對方情況
if (getType(i, j, bwf) == 1) {
x = i;
y = j;
break;
}
if (getType(i, j,1 - bwf) == 1) {
x = i;
y = j;
break;
}
// 預存當前邊界值
int temp1=x_min,temp2=x_max,temp3=y_min,temp4=y_max;
// 預設己方下棋,並更新邊界值
isChessOn[i][j] = bwf;
resetMaxMin(i,j);
// 預測未來
int t = findMin(-100000000, 100000000, deep);
// 還原預設下棋位置以及邊界值
isChessOn[i][j] = 2;
x_min=temp1;
x_max=temp2;
y_min=temp3;
y_max=temp4;
// 差距小於1000,50%機率隨機選取
//
System。out。println
(“外 :” + i + “,” + j + “ mx:” + mx + “ t:” + t);
if (t - mx > 1000 || Math。abs(t - mx)<1000 && randomTest(3)) {
x = i;
y = j;
mx = t;
//
System。out。println
(i + “,” + j + “ mx:” + mx + “ t:” + t);
}
}
System。out。println(“x=”+x+“,y=”+y);
// addChess(x,y,(bwf+1)%2,true);
// repaint();
int step=0;
step++;
System。out。println(“step ”+step+“:————————————————————————-”);
for(int i=0;i<15;i++,System。out。print(“\n”))
for(int j=0;j<15;j++)
{
if(isChessOn[j][i]!=2)System。out。print(isChessOn[j][i]);
else System。out。print(isChessOn[j][i]);
}
// 判斷是否已分勝負
boolean flag = haveWin(x, y, bwf);
//記錄
update( x, y );
repaint();
// 重設邊界值
resetMaxMin(x,y);
// 勝負已分
if (flag)
wined(bwf);
if (!flag && chess_num >= drawn_num) {
win = true;
String str = drawn_num + “步沒分勝負,判和棋!”;
JOptionPane。showMessageDialog(null,str);
return;
}
}
-搜尋當前狀態極大值
alpha :祖先節點得到的當前最小最大值,用於alpha 剪枝
beta :祖先節點得到的當前最大最小值,用於beta 剪枝。
step :還要搜尋的步數
return: 當前搜尋子樹極大值
protected int findMax(int alpha, int beta, int step) {
int max = alpha;
if (step == 0) {
return evaluate();
}
int[][] rt = getBests(1 - sbw);
for (int i = 0; i < rt。length; i++) {
int x = rt[i][0];
int y = rt[i][1];
if (getType(x, y, 1 - sbw) == 1) //電腦可取勝
return 100 * ( getMark(1) + step*1000 );
isChessOn[x][y] = 1 - sbw;
// 預存當前邊界值
int temp1=x_min,temp2=x_max,temp3=y_min,temp4=y_max;
resetMaxMin(x,y);
int t = findMin(max, beta, step - 1);
isChessOn[x][y] = 2;
// 還原預設邊界值
x_min=temp1;
x_max=temp2;
y_min=temp3;
y_max=temp4;
if (t > max)
max = t;
//beta 剪枝
if (max >= beta)
return max;
}
return max;
}
————————————————
版權宣告:本文為CSDN博主「java李陽勇」的原創文章,遵循CC 4。0 BY-SA版權協議,轉載請附上原文出處連結及本宣告。
原文連結:基於Java Swing五子棋小遊戲設計和實現
下一篇:實木大板桌那裡買?