小遊戲?來做個五子棋玩玩

五子棋應該是所有棋類遊戲中規則最簡單的一種了,對應著我們寫代碼,也是最簡單,我們今天就來根據學過的知識,寫一個五子棋玩一玩。

基本界面

五子棋首先要畫出界面,界面其實並不麻煩,但是在畫出界面之前,肯定首先需要計算一下,不然腦子裡面會完全是亂的.

首先,我們約定整個棋盤是 15 * 15 的大小

其次,棋盤格子和格子之間肯定是有距離的,我們約定,每個格子之間的距離是35

當然為了讓棋盤稍微美觀一點,我們可以為棋盤加上一點背景色.為了讓大家看到的更加直觀,整個棋盤的佈局,如下圖:

1.整個Swing界面的大小

小遊戲?來做個五子棋玩玩


2.棋盤的大小

小遊戲?來做個五子棋玩玩


這裡要稍微注意的一點是,這個棋盤是 15 * 15的大小,但是棋盤的格子其實只有14個,所以有線框的部分實際只有 490 * 490 的大小

3.棋盤和Swing邊框周圍的計算

小遊戲?來做個五子棋玩玩


所以,根據上面的圖像,先來編寫代碼

編寫代碼

根據面向對象的思想,將代碼劃分了3個類去編寫:

BoardPanel類專門負責畫出棋盤

Board類負責畫出旗子以及判定勝負

GameFrame類畫出主面板

首先來看畫出棋盤的類BoardPanel.java,既然專門負責畫出棋盤,所以讓這個類直接去繼承Panel類,然後paint出相應的圖像就ok

BoardPanel.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

20
21
22
package com.fivechess;
import javax.swing.*;
import java.awt.*;
public class BoardPanel extends JPanel{
@Override
public void paint(Graphics g) {
g.setColor(new Color(165,185,75));
g.fillRect(35,35,525,525);
g.setColor(Color.BLACK);
//繪製棋盤
for (int i=0; i<15; i++){
g.drawLine(50, 50 + i*35, 540, 50 + i*35);
g.drawLine(50 + i*35, 50, 50 + i*35, 540);
}
//繪製天元(中間的圓點)
g.fillOval(290,290,10,10);
}
}

可以將這個放入到棋盤當如到Swing界面上,編寫代碼創建GameFrame.java

GameFrame.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

19
20
21
public class GameFrame extends JFrame{
private JPanel boardPanel;
public GameFrame(){
this.setTitle("五子棋");
this.setSize(700, 600);
this.setResizable(false);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLayout(null);
boardPanel = new BoardPanel();
boardPanel.setBounds(0, 0, 600,600);
this.add(boardPanel);
}
public static void main(String[] args) {
GameFrame tf = new GameFrame();
tf.setVisible(true);
}
}

這樣執行代碼,一個棋盤就出來了,接下來實現點擊出現棋子,而棋子我們需要單獨的類來生成,編寫Board代碼,並將之前的代碼稍微修改

Board.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public class Board {
private int [][] board = new int[15][15];

public void draw(Graphics g){
for (int i=0; i for (int j=0; j if(board[i][j] != 0){ //如果不是空格
if(board[i][j] == 1){ //如果是黑子
g.setColor(Color.BLACK);
}else{ //白子
g.setColor(Color.white);
}
g.fillOval(35*(j+1),35*(i+1),30,30);
//如果是白子,為了好看,給白子加上邊框
if(board[i][j] == 2){
g.setColor(Color.BLACK);
g.drawOval(35*(j+1),35*(i+1),30,30);
}
}
}
}
}
/**
* 向棋盤中放置棋子

* @param row 行
* @param col 列
* @param isBlack 黑子還是白子
* @return 落子成功true,失敗false(該位置已經有子)
*/
public boolean addPiece(int row, int col, boolean isBlack){
if(board[row][col] == 0){ //沒有棋子的地方才能落子
board[row][col] = isBlack?1:2;
return true;
}
return false;
}
}

修改BoardPanel.java文件,加入棋子的繪製

BoardPanel.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

24
25
26
27
28
29
30
package com.fivechess;
import javax.swing.*;
import java.awt.*;
public class BoardPanel extends JPanel{
private Board b = null;
public BoardPanel(Board b) {
this.b = b;
}
@Override
public void paint(Graphics g) {
g.setColor(new Color(165,185,75));
g.fillRect(35,35,525,525);
g.setColor(Color.BLACK);
//繪製棋盤
for (int i=0; i<15; i++){
g.drawLine(50, 50 + i*35, 540, 50 + i*35);
g.drawLine(50 + i*35, 50, 50 + i*35, 540);
}
//繪製天元(中間的圓點)
g.fillOval(290,290,10,10);
//繪製棋子
b.draw(g);
}
}

修改GameFrame.java代碼,加入鼠標點擊事件和相應的判斷

GameFrame.java

1
2
3
4
5
6
7
8

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package com.fivechess;
import javax.swing.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class GameFrame extends JFrame{

private boolean isBlack = true; //是否黑子 true黑子 false白子
private JPanel boardPanel;
private Board b = new Board();
public GameFrame(){
this.setTitle("五子棋");
this.setSize(700, 600);
this.setResizable(false);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLayout(null);
boardPanel = new BoardPanel(b);
boardPanel.setBounds(0, 0, 600,600);
//在boardPanel下棋需要執行點擊事件
boardPanel.addMouseListener(new MouseHandle());
this.add(boardPanel);
}
private class MouseHandle extends MouseAdapter {
@Override
public void mousePressed(MouseEvent e) {
int x = e.getX();
int y = e.getY();
//點擊事件必須在棋盤內
if( x >= 50 && x<= 540 && y>=50 && y<=540) {
//通過鼠標座標計算出點擊棋盤的行或者列
int row = Math.round((y - 50) / 35F);
int col = Math.round((x - 50) / 35F);
if (b.addPiece(row, col, isBlack)) {
//刷新頁面
repaint();
//黑白子輪流下棋,每次進行替換
isBlack = !isBlack;
}
}
}
}
public static void main(String[] args) {
GameFrame tf = new GameFrame();
tf.setVisible(true);
}
}

這樣,我們就可以再棋盤上落子了,只是還不能判斷輸贏而已

小遊戲?來做個五子棋玩玩


所以接下來,我們在棋子類中加入判斷輸贏的代碼

Board.java

1
2
3
4
5
6
7
8

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58

59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108

109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158

159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
package com.fivechess;
import java.awt.*;
public class Board {
private int [][] board = new int[15][15];
/**
* 繪製棋盤
* @param g
*/
public void draw(Graphics g){
for (int i=0; i for (int j=0; j if(board[i][j] != 0){ //如果不是空格
if(board[i][j] == 1){ //如果是黑子
g.setColor(Color.BLACK);
}else{ //白子
g.setColor(Color.white);
}
g.fillOval(35*(j+1),35*(i+1),30,30);
//如果是白子,為了好看,給白子加上邊框
if(board[i][j] == 2){
g.setColor(Color.BLACK);

g.drawOval(35*(j+1),35*(i+1),30,30);
}
}
}
}
}
/**
* 向棋盤中放置棋子
* @param row 行
* @param col 列
* @param isBlack 黑子還是白子
* @return 落子成功true,失敗false(該位置已經有子)
*/
public boolean addPiece(int row, int col, boolean isBlack){
if(board[row][col] == 0){ //沒有棋子的地方才能落子
board[row][col] = isBlack?1:2;
return true;
}
return false;
}
public boolean isWin(int row, int col, boolean isBlack){
return checkH(row,col,isBlack) || checkV(row, col, isBlack)
|| checkX1(row, col, isBlack) || checkX2(row, col, isBlack);
}
/**
* 從右斜線判斷是否連成5顆
* @param row 行
* @param col 列
* @param isBlack 黑子還是白子
* @return 是否獲勝
*/
public boolean checkX2(int row, int col, boolean isBlack){
int count = 1;
int currentRow = row;
int currentCol = col;
int v = isBlack ? 1 : 2;
//從左下到右上判斷
while(currentRow > 0 && currentCol < 14
&& board[--currentRow][++currentCol] == v){
count ++;
}
currentRow = row;
currentCol = col;

//從右上到左下判斷
while(currentRow < 14 && currentCol > 0
&& board[++currentRow][--currentCol] == v){
count ++;
}
return count >= 5;
}
/**
* 從左斜線判斷是否連成5顆
* @param row 行
* @param col 列
* @param isBlack 黑子白子
* @return 是否獲勝
*/
public boolean checkX1(int row, int col, boolean isBlack){
int count = 1;
int currentRow = row;
int currentCol = col;
int v = isBlack ? 1 : 2;
//從右下到左上判斷
while(currentRow > 0 && currentCol > 0
&& board[--currentRow][--currentCol] == v){
count ++;
}
currentRow = row;
currentCol = col;
//從左上到右下判斷
while(currentRow < 14 && currentCol < 14
&& board[++currentRow][++currentCol] == v){
count ++;
}
return count >= 5;
}
/**
* 豎線判斷是否連成5顆
* @param row
* @param col
* @param isBlack
* @return
*/
public boolean checkV(int row, int col, boolean isBlack){
int count = 1;
int currentRow = row;
int currentCol = col;
int v = isBlack ? 1 : 2;

//從上到下判斷
while(currentRow < 14
&& board[++currentRow][currentCol] == v){
count ++;
}
currentRow = row;
currentCol = col;
//從下到上判斷
while(currentRow > 0
&& board[--currentRow][currentCol] == v){
count ++;
}
return count >= 5;
}
/**
* 橫向判斷是否連成5顆
* @param row
* @param col
* @param isBlack
* @return
*/
public boolean checkH(int row, int col, boolean isBlack){
int count = 1;
int currentRow = row;
int currentCol = col;
int v = isBlack ? 1 : 2;
//從左到右判斷
while(currentCol < 14
&& board[currentRow][++currentCol] == v){
count ++;
}
currentRow = row;
currentCol = col;
//從右到左判斷
while(currentCol > 0
&& board[currentRow][--currentCol] == v){
count ++;
}
return count >= 5;
}
public void clearBoard(){
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[i].length; j++) {
board[i][j] = 0;
}
}
}

}

這裡修改Board.java代碼其實主要就是加上了輸贏判斷,要判斷輸贏,就是判斷橫,輸,左斜,右斜是否連續是一個顏色並且連成5個

小遊戲?來做個五子棋玩玩


最後在GameFrame.java中加入相應的代碼和點擊開始遊戲的按鈕

GameFrame.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package com.fivechess;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class GameFrame extends JFrame {

private boolean isBlack = true; //是否黑子
private Board b = new Board(); //棋盤對象
private boolean isWin = false; //是否勝利
private boolean isStart = false; //是否開始
private class MouseHandle extends MouseAdapter{
@Override
public void mousePressed(MouseEvent e) {
if(isStart && !isWin){
int x = e.getX();
int y = e.getY();
//點擊事件必須在棋盤內
if( x >= 50 && x<= 540 && y>=50 && y<=540){
//通過鼠標座標計算出點擊棋盤的行或者列
int row = Math.round((y - 50) / 35F);
int col = Math.round((x - 50) / 35F);
if(b.addPiece(row,col,isBlack)){
repaint();
isWin = b.isWin(row,col,isBlack);
if(!isWin){
isBlack = !isBlack;
}else{
JOptionPane.showMessageDialog(null,
isBlack ? "黑子勝" : "白子勝");
btnStartGame.setEnabled(true);
}
}
}
}
}
}
private JPanel boardPanel;
private JButton btnStartGame;
private JLabel lblStatus;
public GameFrame() {
this.setTitle("五子棋");
this.setSize(700, 600);
this.setResizable(false);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLayout(null);
//測試顯示每次鼠標點擊的座標
lblStatus = new JLabel("~~~~");
lblStatus.setBounds(580, 200, 150,50);
boardPanel = new BoardPanel(b);

boardPanel.setBounds(0, 0, 600,600);
//在boardPanel下棋需要執行點擊事件
boardPanel.addMouseListener(new MouseHandle());
/**測試座標位置*/
boardPanel.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
lblStatus.setText("座標 x:" + e.getX() + ",y:"+e.getY());
}
});
btnStartGame = new JButton("開始遊戲");
btnStartGame.setBounds(580,100,100,35);
//點擊開始遊戲,初始化變量
btnStartGame.addActionListener(new AbstractAction() {
public void actionPerformed(ActionEvent e) {
isStart = true; //開始遊戲
isWin = false; //開始遊戲之後還沒有輸贏
btnStartGame.setEnabled(false); //點擊之後按鈕不可用
b.clearBoard(); //清空界面,實際就是將數組所有值設置為0
repaint(); //刷新頁面
}
});
this.add(lblStatus);
this.add(boardPanel);
this.add(btnStartGame);
}
public static void main(String[] args) {
GameFrame gf = new GameFrame();
gf.setVisible(true);
}
}


小遊戲?來做個五子棋玩玩

小遊戲?來做個五子棋玩玩



分享到:


相關文章: