Java實現(xiàn)單機版五子棋游戲的示例代碼
前言
五子棋是世界智力運動會競技項目之一,是一種兩人對弈的純策略型棋類游戲,是世界智力運動會競技項目之一,通常雙方分別使用黑白兩色的棋子,下在棋盤直線與橫線的交叉點上,先形成5子連線者獲勝。
棋具與圍棋通用,起源于中國上古時代的傳統(tǒng)黑白棋種之一。主要流行于華人和漢字文化圈的國家以及歐美一些地區(qū),是世界上最古老的棋。
容易上手,老少皆宜,而且趣味橫生,引人入勝;不僅能增強思維能力,提高智力,而且富含哲理,有助于修身養(yǎng)性。
用java語言實現(xiàn),采用了swing技術進行了界面化處理,設計思路用了面向對象思想。
主要需求
1、對局雙方各執(zhí)一色棋子。
2、空棋盤開局。
3、玩家(黑棋)先、AI(紅棋)后,交替下子,每次只能下一子。
4、棋子下在棋盤的空白點上,棋子下定后,不得向其它點移動,不得從棋盤上拿掉或拿起另落別處。
5、黑方的第一枚棋子可下在棋盤任意交叉點上。
6、輪流下子是雙方的權利,但允許任何一方放棄下子權,先形成5子連線者獲勝。
主要設計
1、由于是單機的游戲,啟動游戲后,可直接開始游戲。
2、游戲規(guī)則:
- 對局雙方各執(zhí)一色棋子。
- 空棋盤開局。
- 黑先、紅后,交替下子,每次只能下一子。
- 棋子下在棋盤的空白點上,棋子下定后,不得向其它點移動,不得從棋盤上拿掉或拿起另落別處。
- 黑方的第一枚棋子可下在棋盤任意交叉點上。
- 輪流下子是雙方的權利,但允許任何一方放棄下子權,先形成5子連線者獲勝。
3、設計排行榜功能
統(tǒng)計局數(shù),步數(shù)和結果
4、更換棋盤
可以切換不同的棋盤,下棋更加賞心悅目。
5、更換棋子
可以芀不同的棋子顏色。
功能截圖
啟動游戲:

對戰(zhàn)效果

切換棋盤:

代碼實現(xiàn)
主界面:
package wuziqi;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
public class Wumain extends JFrame{
Pan p = null;
JMenuBar menuber = new JMenuBar();
JMenu jm1 = new JMenu("選項");
JMenu jm2 = new JMenu("設置");
JMenu jm3 = new JMenu("幫助");
JMenuItem jm1_1 = new JMenuItem("重新開始");
JMenuItem jm1_2 = new JMenuItem(" 排行榜");
JMenuItem jm1_3 = new JMenuItem("退出游戲");
JMenuItem jm2_1 = new JMenuItem("更換棋盤");
JMenuItem jm2_2 = new JMenuItem("更換棋子");
JMenuItem jm3_1 = new JMenuItem("關于我們");
public Wumain()
{
p =new Pan();
this.setSize(585,600);
this.setLocation(200,100);
this.add(p);
this.setResizable(false);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jm1.add(jm1_1);
jm1.add(jm1_2);
jm1.add(jm1_3);
jm2.add(jm2_1);
jm2.add(jm2_2);
jm3.add(jm3_1);
menuber.add(jm1);
menuber.add(jm2);
menuber.add(jm3);
this.setJMenuBar(menuber);
this.addMouseListener(p);
jm1_3.addActionListener(new ActionListener() {
// 匿名虛構類
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
jm1_1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
for(int i=0;i<p.row;i++){
for(int j=0;j<p.col;j++){
p.num[i][j] = 0;
}
}
p.canSetqizi = true;
p.qizi_num = 0;
repaint();
}
});
jm2_1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Random r = new Random();
int n = r.nextInt(8);
String qipan_name = "qipan"+n+".jpg";
p.qipan_name = qipan_name;
repaint();
}
});
jm2_2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Random r = new Random();
int n = r.nextInt(8);
String qizi1_name = "c"+n+".png";
String qizi2_name = "c"+(n+1)+".png";
p.qizi1_name = qizi1_name;
p.qizi2_name = qizi2_name;
repaint();
}
});
jm3_1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String msg ="關于我們\n" +
"1、玩家先落子;\n" +
"2、形成5顆同色連子即為贏;\n\n\n" +
" ";
JOptionPane.showMessageDialog(null, msg);
}
});
jm1_2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String msg ="排行榜\n" +
"局數(shù) 步數(shù) 結果\n";
for(int i=0;i<p.paihanglist.size();i++)
{
PaiHangBang ph = p.paihanglist.get(i);
msg = msg+" "+ph.getJushu()
+" "+ph.getBushu()
+" "+ph.getJieguo()+"\n";
}
JOptionPane.showMessageDialog(null, msg);
}
});
this.setVisible(true);
}
public static void main(String[] args){
Wumain w = new Wumain();
}
}排行榜
package wuziqi;
public class PaiHangBang {
private int jushu;
private int bushu;
private String jieguo;
public int getJushu() {
return jushu;
}
public void setJushu(int jushu) {
if(jushu<1){
this.jushu = 1;
}
this.jushu = jushu;
}
public int getBushu() {
return bushu;
}
public void setBushu(int bushu) {
this.bushu = bushu;
}
public String getJieguo() {
return jieguo;
}
public void setJieguo(String jieguo) {
this.jieguo = jieguo;
}
}棋盤
package wuziqi;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class Pan extends JPanel implements MouseListener{
int i=0,j=0;
int row = 15;
// 數(shù)組下標
int col = 15;
// 數(shù)組上標
String qipan_name = "qipan1.jpg";
String qizi1_name = "c1.png";
String qizi2_name = "c2.png";
int num[][] = new int[row][col];
// 0:標示該位置為空,1:標示紅棋子,2:標示黑棋子
boolean canSetqizi = true;
// 定義boolean值,用來判斷該位置是否有子
int qizi_num = 0;
// 定義記錄落子數(shù)
List<PaiHangBang> paihanglist = new ArrayList();
// 定義集合,用來存儲排行榜
public void paint(Graphics g){
super.paint(g);
Image img= new ImageIcon("img/"+qipan_name).getImage();
// 調入棋盤圖片
g.drawImage(img, 0, 0, 567, 567, this);
// 繪制棋盤
Image c1= new ImageIcon("img/"+qizi1_name).getImage();
Image c2= new ImageIcon("img/"+qizi2_name).getImage();
for(int i = 0;i<num.length;i++){
for(int j = 0;j<num[i].length;j++){
if(num[i][j] == 1)
{
g.drawImage(c1, i*35+20, j*35+20, 35, 35, this);
}
else if(num[i][j] == 2)
{
g.drawImage(c2, i*35+20, j*35+20, 35, 35, this);
}
}
// 重繪棋子
}
// 重載整個界面(防止最小化后原內容丟失)
}
public int[] getLoc(int x,int y) {
int count = 1;
// 定義計數(shù)器,用于計算棋子數(shù)
int[] wz1 = null;
int[] wz2 = null;
// 定義數(shù)組,用來存儲危險位置
for(int i =x-1;i>=0;i--){
if(num[i][y] == num[x][y])
{
count++;
}
else
{
if(num[i][y] == 0){
wz1 = new int[]{i,y};
// 獲取左邊的危險位置坐標
}
break;
}
}
// 左
for(int i =x+1;i<row;i++){
if(num[i][y] == num[x][y])
{
count++;
}else{
if(num[i][y] == 0){
wz2 = new int[]{i,y};
// 獲取有變位置危險坐標
}
break;
}
}
// 右
if(count>=3)
{
if(wz1 != null){
return wz1;
// 判斷返回左邊危險位置
}else if(wz2 != null){
return wz2;
// 判斷返回右邊危險位置
}else{
return null;
}
}
// 左右
count = 1;
wz1 = null;
wz2 = null;
// 初始化所有參數(shù)
for(int j =y-1;j>=0;j--){
if(num[x][j] == num[x][y])
{
count++;
}
else
{
if(num[x][j] == 0){
wz1 = new int[]{x,j};
}
break;
}
}
// 上
for(int j =y+1;j<col;j++){
if(num[x][j] == num[x][y])
{
count++;
}else{
if(num[x][j] == 0){
wz2 = new int[]{x,j};
}
break;
}
}
// 下
if(count>=3)
{
if(wz1 != null){
return wz1;
}else if(wz2 != null){
return wz2;
}else{
return null;
}
}
// 上下
count = 1;
wz1 = null;
wz2 = null;
for(int i =x-1,j =y-1;i>=0&&j>=0;i--,j--){
if(num[i][j] == num[x][y])
{
count++;
}
else
{
if(num[i][j] == 0){
wz1 = new int[]{i,j};
}
break;
}
}
// 左上
for(int i =x+1,j =y+1;i<row&&j<col;i++,j++){
if(num[i][j] == num[x][y])
{
count++;
}else{
if(num[i][j] == 0){
wz2 = new int[]{i,j};
}
break;
}
}
// 右下
if(count>=3)
{
if(wz1 != null){
return wz1;
}else if(wz2 != null){
return wz2;
}else{
return null;
}
}
// 左上右下
count = 1;
wz1 = null;
wz2 = null;
for(int i =x-1,j =y+1;i>=0&&j<col;i--,j++){
if(num[i][j] == num[x][y])
{
count++;
}
else
{
if(num[i][j] == 0){
wz1 = new int[]{i,j};
}
break;
}
}
// 左下
for(int i =x+1,j =y-1;i<row&&j>=0;i++,j--){
if(num[i][j] == num[x][y])
{
count++;
}else{
if(num[i][j] == 0){
wz2 = new int[]{i,j};
}
break;
}
}
// 右上
if(count>=3)
{
if(wz1 != null){
return wz1;
}else if(wz2 != null){
return wz2;
}else{
return null;
}
}
// 左下右上
return null;
}
public boolean iswin(int x,int y){
int count = 1;
for(int i =x-1;i>=0;i--){
if(num[i][y] == num[x][y])
{
count++;
}
else
{
break;
}
}
// 左
for(int i =x+1;i<row;i++){
if(num[i][y] == num[x][y])
{
count++;
}else{
break;
}
}
// 右
if(count>=5)
{
return true;
}
// 左右
count = 1;
for(int j =y-1;j>=0;j--){
if(num[x][j] == num[x][y])
{
count++;
}
else
{
break;
}
}
// 上
for(int j =y+1;j<col;j++){
if(num[x][j] == num[x][y])
{
count++;
}else{
break;
}
}
// 下
if(count>=5)
{
return true;
}
// 上下
count = 1;
for(int i =x-1,j =y-1;i>=0&&j>=0;i--,j--){
if(num[i][j] == num[x][y])
{
count++;
}
else
{
break;
}
}
// 左上
for(int i =x+1,j =y+1;i<row&&j<col;i++,j++){
if(num[i][j] == num[x][y])
{
count++;
}else{
break;
}
}
// 右下
if(count>=5)
{
return true;
}
// 左上右下
count = 1;
for(int i =x-1,j =y+1;i>=0&&j<col;i--,j++){
if(num[i][j] == num[x][y])
{
count++;
}
else
{
break;
}
}
// 左下
for(int i =x+1,j =y-1;i<row&&j>=0;i++,j--){
if(num[i][j] == num[x][y])
{
count++;
}else{
break;
}
}
// 右上
if(count>=5)
{
return true;
}
// 左下右上
return false;
}
// 判斷輸贏
@Override
public void mouseClicked(MouseEvent e) {
if(canSetqizi){
Graphics g = this.getGraphics();
int checkusersuccess = 0;
// 標示是否落子成功
int x = e.getX();
int y = e.getY();
// 獲取鼠標點擊的位置
Image c1= new ImageIcon("img/"+qizi1_name).getImage();
int i = (x-25)/35;
int j = (y-75)/35;
if(num[i][j] != 0){
JOptionPane.showMessageDialog(null, "該位置有旗子,請重新落子");
return;
// 判斷有子,終止本次事件,進行下次事件觸發(fā)
}else{
g.drawImage(c1, i*35+20, j*35+20, 35, 35, this);
// 畫出玩家落子
num[i][j] = 1;
// 給數(shù)組付一個只值,表示該位置有旗子
checkusersuccess = 1;
// 標示量標示
qizi_num++;
// 記錄玩家落子步數(shù)
}
boolean b=iswin(i,j);
if(b){
JOptionPane.showMessageDialog(null, "你贏了!");
canSetqizi = false;
PaiHangBang ph = new PaiHangBang();
ph.setJushu(paihanglist.size()+1);
ph.setBushu(qizi_num);
ph.setJieguo("win");
paihanglist.add(ph);
return;
}
// 調用boolean判斷方法
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
// 時間間隔:玩家落子后的等待
Random r = new Random();
Image c2 = new ImageIcon("img/"+qizi2_name).getImage();
// 調入黑棋子圖片
do{
int[] wz =getLoc(i, j);
if(wz == null){
i = r.nextInt(15);
j = r.nextInt(15);
}else{
i=wz[0];
j=wz[1];
}
// 設置隨機的坐標
}while(num[i][j] != 0);
g.drawImage(c2, i*35+20, j*35+20, 35, 35, this);
num[i][j] = 2;
boolean d=iswin(i,j);
if(d){
JOptionPane.showMessageDialog(null, "你輸了!");
canSetqizi = false;
PaiHangBang ph = new PaiHangBang();
ph.setJushu(paihanglist.size()+1);
ph.setBushu(qizi_num);
ph.setJieguo("fail");
paihanglist.add(ph);
return;
}
// 隨機電腦落子位置;
}
}
@Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
@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
}
}總結
通過此次的《五子棋單機版》游戲實現(xiàn),讓我對swing的相關知識有了進一步的了解,對java這門語言也有了比以前更深刻的認識。
java的一些基本語法,比如數(shù)據(jù)類型、運算符、程序流程控制和數(shù)組等,理解更加透徹。java最核心的核心就是面向對象思想,對于這一個概念,終于悟到了一些。
以上就是Java實現(xiàn)單機版五子棋游戲的示例代碼的詳細內容,更多關于Java五子棋的資料請關注腳本之家其它相關文章!
相關文章
Mybatis通過攔截器實現(xiàn)單數(shù)據(jù)源內多數(shù)據(jù)庫切換
這篇文章主要為大家詳細介紹了Mybatis如何通過攔截器實現(xiàn)單數(shù)據(jù)源內多數(shù)據(jù)庫切換,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下2023-12-12
Java 日期格式y(tǒng)yyy-MM-dd與YYYY-MM-dd區(qū)別
我們在java中常用的規(guī)范格式為:2023-11-11
yyyy-MM-dd HH:mm:ss:SSS 24小時制或yyyy-MM-dd hh:mm:ss:SSS 12小時制,本文就來介紹一下兩者的區(qū)別,感興趣的可以了解一下
關于feign對x-www-form-urlencode類型的encode和decode問題
這篇文章主要介紹了關于feign對x-www-form-urlencode類型的encode和decode問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03

