实践周java基础软件开发app之五子棋
五子棋人机对战实践项目
总的任务和目标
完成一个人机对战的五子棋项目,基本效果如下:
第一部分 Java绘图原理
1. 基本概念
像素,坐标
第二部分 绘制棋盘
1. 基本思路
在一个JPanel上绘制一个背景,然后绘制水平和垂直的若干条线,使其构成等距离的格子,通常是15*15(条线)。
2. 代码实现
第三部分 绘制棋子
1. 基本思路
使用drawOval()可以绘制空心的圆,使用fillOval()可以填充实心的圆。
2. 坐标计算
由于格子是水平和垂直的有下标的,而绘制时需要使用实际的像素坐标,所以,需要进行行列下标到像素坐标的转换:
int x = col * GRID_WIDTH;
int y = row * GRID_WIDTH;
3. 代码实现
(1) ChessPanel代码:
第四部分 鼠标下棋
1. 基本思路
需要处理鼠标单点事件,获取鼠标所在的位置,然后计算出应该绘制棋子的行列下标,并使用一个二维数组来全局存储棋子的位置。
2. 鼠标位置与行列下标计算
int x = e.getX();
int y = e.getY();
int row = y / GRID_WIDTH;
int col = x / GRID_WIDTH;
3. 代码实现
(1) ChessPanel属性和构造方法代码:
(2)监听器类(内部类)代码:
(3)绘图代码:
第五部分 判断胜负
1. 基本思路
判断胜负是因为在当前位置(row, col)落子导致了胜负,所以,判断胜负其实是在当前落子位置为中心,横向搜索左边第4个位置开始到右边第4个位置(其余位置不需要考虑),或者从上到下,或者正向45度,或者反向45度位置。
2. 处理方法
处理方法有很多,可以采用计数的方式,也可以采用字符串连接的方式,此处采用了将从左边第4颗开始,到右边第4颗结束,将每颗的颜色表示成字符1(黑色)或者2(白色),只需要判断其中是否有连续的5个1或5个2,即“11111”或“22222”即可知道胜负。
3. 代码实现
(1) 监听器类(内部类)代码:
(2)checkWin判断胜负的代码:
/** 判断胜负
* @param row 落子的行下标
* @param col 落子的列下标
* @return 是否获胜,true-是,false-否
*/
public boolean checkWin(int row, int col) {}
(3)重置游戏状态
【目前代码】
1 package wuziqi; 2 3 import java.awt.Color; 4 import java.awt.Container; 5 import java.awt.Graphics; 6 import java.awt.event.MouseAdapter; 7 import java.awt.event.MouseEvent; 8 9 import javax.swing.JFrame; 10 import javax.swing.JOptionPane; 11 import javax.swing.JPanel; 12 13 public class wuziqijiemianDemo { 14 //创建窗口为主类的类部类并且继承自JFrame 15 public class Myjframe extends JFrame { 16 /** 17 * 用一个构造方法创建窗口 18 */ 19 public Myjframe() { 20 this.setTitle("五子棋"); 21 this.setSize(620, 640); 22 //获取内容面板 23 Container cp = getContentPane(); 24 //创建一个面板JPanel 25 JPanel jPanel = new MyJanel(); 26 cp.add(jPanel); 27 //面板的背景颜色为黄色,便于下白棋与黑棋 28 jPanel.setBackground(Color.yellow); 29 this.setDefaultCloseOperation(DISPOSE_ON_CLOSE); 30 //窗口默认设置为显示屏的正中间 31 this.setLocationRelativeTo(null); 32 //不可改变窗口的大小 33 this.setResizable(false); 34 } 35 } 36 /** 37 * 创建一个面板继承自JPanel 38 * @author Administrator 39 * 40 */ 41 public class MyJanel extends JPanel { 42 //表示每个方格的大小 43 private static final int GRID_WIDTh = 40; 44 //棋盘的大小,代表棋盘的线的条数 45 private static final int LINE_COUNT = 15; 46 //设置黑棋子为1、白棋子为2、没有棋子为0(默认值) 47 public static final int BLACK=1; 48 public static final int WHITE=2; 49 //定义一个棋盘大小的数组用来存放黑棋和白棋的位置 50 int[][] chessItems=new int[LINE_COUNT][LINE_COUNT]; 51 //定义一个标志位,代表黑棋先下(黑棋和白棋轮流下棋) 52 int flag=BLACK; 53 /** 54 * 构造方法用来画棋盘的棋子 55 */ 56 public MyJanel(){ 57 /** 58 * 为这个面板添加一个鼠标点击事件,鼠标每点击一次,就在棋盘上下一个棋子 59 *使用适配器的方式添加鼠标点击事件 60 */ 61 this.addMouseListener(new MouseAdapter() { 62 public void mouseClicked(MouseEvent e){ 63 /** 64 * 获取当前的鼠标点击的位置 65 */ 66 int x=e.getX(); 67 int y=e.getY(); 68 /** 69 * 因为棋盘是用二维数组的方式表示的,所以最后表示为二维数组的行与列 70 */ 71 int row=y/GRID_WIDTh; 72 int col=x/GRID_WIDTh; 73 //当前这个位置没有棋子(为零),可以下一个黑棋子 74 if(chessItems[row][col]==0){ 75 if(flag==BLACK){ 76 chessItems[row][col]=flag; 77 //下完黑棋下白棋 78 flag=WHITE; 79 //必须有,不然后面的白棋会覆盖黑棋 80 } 81 //当前这个位置没有棋子(为零),可以下一个白棋子 82 else{ 83 chessItems[row][col]=flag; 84 //下完白棋下黑棋 85 flag=BLACK; 86 } 87 } 88 /** 89 * 每当下完一步棋之后便判断是否已经取胜 90 */ 91 if(checkImage(row,col)){ 92 //显示对话窗口 93 JOptionPane.showMessageDialog(null, "your win"); 94 //清空棋盘 95 clear(); 96 } 97 //System.out.println(chessItems[row][col]); 98 } 99 }); 100 } 101 /** 102 * 调用public void paintComponent(Graphics arg0){};方法画图 103 */ 104 public void paintComponent(Graphics g) { 105 //系统调用 106 super.paintComponent(g); 107 // g.setColor(Color.yellow); 108 // g.fillRect(0, 0, jPanel.width(),jPanel.height()); 109 /** 110 * 画横线,起始位置在窗口左上定点(GRID_WIDTh/2,GRID_WIDTh/2) 111 */ 112 for (int i = 0; i < LINE_COUNT; i++) { 113 int x1 = GRID_WIDTh / 2; 114 int y1 = GRID_WIDTh / 2 + i * GRID_WIDTh; 115 int x2 = x1 + (LINE_COUNT-1)* GRID_WIDTh; 116 int y2 = y1; 117 //画线 118 g.drawLine(x1, y1, x2, y2); 119 } 120 /** 121 * 画竖线 122 */ 123 for (int i = 0; i < LINE_COUNT; i++) { 124 int x1 = GRID_WIDTh / 2 + i * GRID_WIDTh; 125 int y1 = GRID_WIDTh / 2; 126 int x2 = x1; 127 int y2 = y1 + (LINE_COUNT-1) * GRID_WIDTh; 128 //画线 129 g.drawLine(x1, y1, x2, y2); 130 } 131 /** 132 * 遍历这个数组 133 */ 134 for(int row=0;row<LINE_COUNT;row++){ 135 for(int col=0;col<LINE_COUNT;col++){ 136 //判断数组当前值,来画棋子 137 switch (chessItems[row][col]) { 138 case WHITE:chessItem(row, col, Color.WHITE, g);break; 139 case BLACK:chessItem(row, col, Color.BLACK, g);break; 140 } 141 repaint(); 142 } 143 } 144 }; 145 /** 146 * 清空数组,便于下次下棋 147 */ 148 private void clear() { 149 for(int row=0;row<LINE_COUNT;row++){ 150 for(int col=0;col<LINE_COUNT;col++){ 151 //全部置为0 152 chessItems[row][col]=0; 153 } 154 } 155 //重画一遍棋盘 156 repaint(); 157 } 158 /** 159 * 用于判断是否已经取胜 160 * @param row 161 * @param col 162 * @return 163 */ 164 private boolean checkImage(int row, int col) { 165 /** 166 * 判断横行是否win 167 */ 168 StringBuilder stringBuilder=new StringBuilder(); 169 //记录当前存在字符串中的数据个数 170 int count=0; 171 for(int i=-4;i<=4;i++){ 172 int Newcol=col+i; 173 if(Newcol>=0&&Newcol<LINE_COUNT){ 174 count++; 175 stringBuilder.append(chessItems[row][Newcol]); 176 } 177 } 178 if(stringBuilder.indexOf("11111")>=0||stringBuilder.indexOf("22222")>=0){ 179 return true; 180 }else { 181 //如果当前不能赢,则清空字符串 182 stringBuilder.delete(0, count); 183 count=0; 184 } 185 /** 186 * 判断竖行是否win 187 */ 188 for(int i=-4;i<=4;i++){ 189 int Newrow=row+i; 190 if(Newrow>=0&&Newrow<LINE_COUNT){ 191 count++; 192 stringBuilder.append(chessItems[Newrow][col]); 193 } 194 } 195 if(stringBuilder.indexOf("11111")>=0||stringBuilder.indexOf("22222")>=0){ 196 return true; 197 }else { 198 stringBuilder.delete(0, count); 199 count=0; 200 } 201 /** 202 * 判断负45°是否win 203 */ 204 for(int i=-4;i<=4;i++){ 205 int Newcol=col+i; 206 int Newrow=row+i; 207 if(Newcol>=0&&Newcol<LINE_COUNT&&Newrow>=0&&Newrow<LINE_COUNT){ 208 count++; 209 stringBuilder.append(chessItems[Newrow][Newcol]); 210 } 211 } 212 if(stringBuilder.indexOf("11111")>=0||stringBuilder.indexOf("22222")>=0){ 213 return true; 214 }else { 215 stringBuilder.delete(0, count); 216 count=0; 217 } 218 /** 219 * 判断正45°是否win 220 */ 221 for(int i=-4;i<=4;i++){ 222 int Newcol=col+i; 223 int Newrow=row-i; 224 if(Newcol>=0&&Newcol<LINE_COUNT&&Newrow>=0&&Newrow<LINE_COUNT){ 225 count++; 226 stringBuilder.append(chessItems[Newrow][Newcol]); 227 } 228 } 229 if(stringBuilder.indexOf("11111")>=0||stringBuilder.indexOf("22222")>=0){ 230 return true; 231 }else { 232 stringBuilder.delete(0, count); 233 count=0; 234 } 235 return false; 236 } 237 //画棋子 238 public void chessItem(int row,int col,Color color,Graphics graphics){ 239 //x与y分别代表在面板上的位置 240 int x=col*GRID_WIDTh; 241 int y=row*GRID_WIDTh; 242 graphics.setColor(color); 243 //画圆 244 graphics.fillOval(x, y, GRID_WIDTh,GRID_WIDTh); 245 } 246 } 247 248 public static void main(String[] args) { 249 /** 250 * 使用一个java类来创建一个主类为wuziqijiemianDemo,其中的窗口与棋盘为该主类的内部类 251 */ 252 //使用类部类的方式创建一个窗口引用对象(方式为 外部类名.内部类名 变量名=new 外部类名().new 内部类名();) 253 wuziqijiemianDemo.Myjframe myjframe = new wuziqijiemianDemo().new Myjframe(); 254 //设置窗口可见 255 myjframe.setVisible(true); 256 } 257 258 }
第六部分 人机对战
1. 基本思路
当人点了鼠标落子以后,轮到电脑下棋,电脑的基本思想就是,在棋盘的空白处的每个位置,进行判断,当前位置的进攻指数和防守指数分别为多少,在进攻指数和防守指数中取一个较大值作为当前位置的评估值,在整个棋盘的所有空白处找到一个最大值,最大值的那个位置即为应该落子的位置。
2. 代码实现
(1)监听器类(内部类)代码:
(2)电脑下棋的代码
(3) 评估关键参数代码:
(4) 评估方法代码:
【自己代码】
1 package wuziqi; 2 3 import java.awt.Color; 4 import java.awt.Container; 5 import java.awt.Graphics; 6 import java.awt.Image; 7 import java.awt.Point; 8 import java.awt.event.MouseAdapter; 9 import java.awt.event.MouseEvent; 10 import java.io.File; 11 import java.io.IOException; 12 13 import javax.imageio.ImageIO; 14 import javax.swing.JFrame; 15 import javax.swing.JOptionPane; 16 import javax.swing.JPanel; 17 18 public class wuziqijiemianDemo { 19 // 创建窗口为主类的类部类并且继承自JFrame 20 public class Myjframe extends JFrame { 21 /** 22 * 用一个构造方法创建窗口 23 */ 24 public Myjframe() { 25 this.setTitle("五子棋"); 26 this.setSize(620, 640); 27 // 获取内容面板 28 Container cp = getContentPane(); 29 // 创建一个面板JPanel 30 JPanel jPanel = new MyJanel(); 31 cp.add(jPanel); 32 // 面板的背景颜色为黄色,便于下白棋与黑棋 33 jPanel.setBackground(Color.yellow); 34 this.setDefaultCloseOperation(DISPOSE_ON_CLOSE); 35 // 窗口默认设置为显示屏的正中间 36 this.setLocationRelativeTo(null); 37 // 不可改变窗口的大小 38 this.setResizable(false); 39 } 40 } 41 42 /** 43 * 创建一个面板继承自JPanel 44 * 45 * @author Administrator 46 * 47 */ 48 public class MyJanel extends JPanel { 49 // 表示每个方格的大小 50 private static final int GRID_WIDTh = 40; 51 // 棋盘的大小,代表棋盘的线的条数 52 private static final int LINE_COUNT = 15; 53 // 设置黑棋子为1、白棋子为2、没有棋子为0(默认值) 54 public static final int BLACK = 1; 55 public static final int WHITE = 2; 56 // 定义一个棋盘大小的数组用来存放黑棋和白棋的位置 57 int[][] chessItems = new int[LINE_COUNT][LINE_COUNT]; 58 // 定义一个标志位,代表黑棋先下(黑棋和白棋轮流下棋) 59 int flag = BLACK; 60 //定义一个方框标记计算机下棋的棋子 61 private Point lastpoint=new Point(); 62 //利用图片代表棋子 63 Image blackImage=null; 64 Image whiImage=null; 65 //定义一个进攻的数组 66 String[] defendstring={ 67 "11111","011110","11110","01111","11011", 68 "10111","11101","01110","11100","00111", 69 "0111","1110","1011","1101","111", 70 "01100","00110","011","110","11" 71 }; 72 //定义一个防守的数组 73 String[] attackstring={ 74 "22222","022220","22220","02222","22022", 75 "20222","22202","02220","22200","00222", 76 "0222","2220","2022","2202","222", 77 "02200","00220","022","220","22" 78 }; 79 //定义一个防守与进攻对应的得分 80 int[] score={ 81 100,90,80,80,80, 82 80,80,70,60,60, 83 50,50,50,50,40, 84 30,30,20,20,10, 85 }; 86 /** 87 * 构造方法用来画棋盘的棋子 88 */ 89 public MyJanel() { 90 /** 91 * 将棋子改变为图片,将黑子白子图片导入进来 92 */ 93 try { 94 blackImage=ImageIO.read(new File("imgs/black.png")); 95 whiImage=ImageIO.read(new File("imgs/WHITE.png")); 96 } catch (IOException e1) { 97 // TODO Auto-generated catch block 98 e1.printStackTrace(); 99 } 100 /** 101 * 为这个面板添加一个鼠标点击事件,鼠标每点击一次,就在棋盘上下一个棋子 使用适配器的方式添加鼠标点击事件 102 */ 103 this.addMouseListener(new MouseAdapter() { 104 public void mouseClicked(MouseEvent e) { 105 /** 106 * 获取当前的鼠标点击的位置 107 */ 108 int x = e.getX(); 109 int y = e.getY(); 110 /** 111 * 因为棋盘是用二维数组的方式表示的,所以最后表示为二维数组的行与列 112 */ 113 int row = y / GRID_WIDTh; 114 int col = x / GRID_WIDTh; 115 // 当前这个位置没有棋子(为零),可以下一个黑棋子 116 if (chessItems[row][col] == 0) { 117 //人先下黑棋 118 chessItems[row][col] = flag; 119 /** 120 * 每当下完一步棋之后便判断是否已经取胜 121 */ 122 if (checkImage(row, col)) { 123 JOptionPane.showMessageDialog(null, "你赢了"); 124 clear(); 125 return; 126 } 127 // 人下完黑棋下白棋,之后再给计算机下黑棋的机会 128 flag = WHITE; 129 //计算机下棋 130 computerPlay(); 131 // 计算机下完摆起之后,给人下黑棋的机会 132 flag = BLACK; 133 // 必须有,不然后面的白棋会覆盖黑棋 134 } 135 // System.out.println(chessItems[row][col]); 136 } 137 //计算机下棋调用方法 138 private void computerPlay() { 139 // 当前初始化找到的位置和期望值 140 int tempRow = -1, tempCol = -1, maxValue = 0; 141 // 遍历数组一个位置一个位置的找 142 for (int i = 0; i < LINE_COUNT; i++) { 143 for (int j = 0; j < LINE_COUNT; j++) { 144 // 如果这个位置已经下棋,则跳过 145 if (chessItems[i][j] > 0) { 146 continue; 147 } 148 // 表示进攻得分和防守得分 149 int attack = CheckMax(i, j, WHITE); 150 int defend= CheckMax(i, j, BLACK); 151 int max = Math.max(attack, defend); 152 // 获取最大值,并记录下标 153 if (max > maxValue) { 154 tempRow = i; 155 tempCol = j; 156 maxValue = max; 157 } 158 } 159 } 160 //如果当前计算机没有找到下棋的位置,表明为平局 161 if(tempCol<0||tempRow<0){ 162 JOptionPane.showMessageDialog(null, "平局"); 163 clear(); 164 return; 165 }else{ 166 // 计算机下白棋,下完之后人下黑棋,画一遍 167 chessItems[tempRow][tempCol] = WHITE; 168 lastpoint.x=tempRow; 169 lastpoint.y=tempCol; 170 repaint(); 171 } 172 // 计算机下完棋之后便判断自己是否已经获胜 173 if (checkImage(tempRow, tempCol)) { 174 JOptionPane.showMessageDialog(null, "你输了"); 175 clear(); 176 return; 177 } 178 } 179 //计算机查看当前位置(黑棋与白棋) 180 private int CheckMax(int row, int col, int current_colorpointer) { 181 //max记录最大的期望,而tempmax记录当前的期望 182 int max=0,tempmax=0; 183 //判断当前是进攻还是防守 184 String[] array=current_colorpointer==WHITE?attackstring:defendstring; 185 //用一个字符串存放当前的状态 186 StringBuilder stringBuilder=new StringBuilder(); 187 //水平方向 188 for (int i = -4; i <= 4; i++) { 189 int Newcol = col + i; 190 if (Newcol<0 ||Newcol >= LINE_COUNT) { 191 continue; 192 } 193 //假装先把这个位置下棋,实质上并没有下棋 194 if(i==0){ 195 stringBuilder.append(current_colorpointer); 196 }else{ 197 stringBuilder.append(chessItems[row][Newcol]); 198 } 199 } 200 for(int i=0;i<array.length;i++){ 201 String string=array[i]; 202 //查找匹配字符串数组,并计算出期望值,找到即跳出循环 203 if(stringBuilder.indexOf(string)>=0){ 204 max=score[i]; 205 break; 206 } 207 } 208 //如果当前为最大的期望,即可以获胜,就直接return 209 if(max==100){ 210 return max; 211 } 212 //每次在每个方向判断之后,应该清空当前的stringBuilder字符串 213 stringBuilder.delete(0, stringBuilder.length()); 214 //垂直方向 215 for (int i = -4; i <= 4; i++) { 216 int Newrow = row + i; 217 if (Newrow<0 ||Newrow >= LINE_COUNT) { 218 continue; 219 } 220 if(i==0){ 221 stringBuilder.append(current_colorpointer); 222 }else{ 223 stringBuilder.append(chessItems[Newrow][col]); 224 } 225 } 226 tempmax=0; 227 for(int i=0;i<array.length;i++){ 228 String string=array[i]; 229 if(stringBuilder.indexOf(string)>=0){ 230 tempmax=score[i]; 231 break; 232 } 233 } 234 if(max<tempmax){ 235 max=tempmax; 236 } 237 if(max==100){ 238 return max; 239 } 240 //每次在每个方向判断之后,应该清空当前的stringBuilder字符串 241 stringBuilder.delete(0, stringBuilder.length()); 242 //负45° 243 for (int i = -4; i <= 4; i++) { 244 int Newrow = row + i; 245 int Newcol = col + i; 246 if ((Newrow<0 ||Newrow >= LINE_COUNT||Newcol<0 ||Newcol >= LINE_COUNT)) { 247 continue; 248 } 249 if(i==0){ 250 stringBuilder.append(current_colorpointer); 251 }else{ 252 stringBuilder.append(chessItems[Newrow][Newcol]); 253 } 254 } 255 tempmax=0; 256 for(int i=0;i<array.length;i++){ 257 String string=array[i]; 258 if(stringBuilder.indexOf(string)>=0){ 259 tempmax=score[i]; 260 break; 261 } 262 } 263 if(max<tempmax){ 264 max=tempmax; 265 } 266 if(max==100){ 267 return max; 268 } 269 //每次在每个方向判断之后,应该清空当前的stringBuilder字符串 270 stringBuilder.delete(0, stringBuilder.length()); 271 //正45° 272 for (int i = -4; i <= 4; i++) { 273 int Newrow = row + i; 274 int Newcol = col - i; 275 if ((Newrow<0 ||Newrow >= LINE_COUNT||Newcol<0 ||Newcol >= LINE_COUNT)) { 276 continue; 277 } 278 if(i==0){ 279 stringBuilder.append(current_colorpointer); 280 }else{ 281 stringBuilder.append(chessItems[Newrow][Newcol]); 282 } 283 } 284 tempmax=0; 285 for(int i=0;i<array.length;i++){ 286 String string=array[i]; 287 if(stringBuilder.indexOf(string)>=0){ 288 tempmax=score[i]; 289 break; 290 } 291 } 292 if(max<tempmax){ 293 max=tempmax; 294 } 295 if(max==100){ 296 return max; 297 } 298 return max; 299 } 300 }); 301 } 302 303 /** 304 * 调用public void paintComponent(Graphics arg0){};方法画图 305 */ 306 public void paintComponent(Graphics g) { 307 // 系统调用 308 super.paintComponent(g); 309 // g.setColor(Color.yellow); 310 // g.fillRect(0, 0, jPanel.width(),jPanel.height()); 311 /** 312 * 画横线,起始位置在窗口左上定点(GRID_WIDTh/2,GRID_WIDTh/2) 313 */ 314 for (int i = 0; i < LINE_COUNT; i++) { 315 int x1 = GRID_WIDTh / 2; 316 int y1 = GRID_WIDTh / 2 + i * GRID_WIDTh; 317 int x2 = x1 + (LINE_COUNT - 1) * GRID_WIDTh; 318 int y2 = y1; 319 // 画线 320 g.drawLine(x1, y1, x2, y2); 321 } 322 /** 323 * 画竖线 324 */ 325 for (int i = 0; i < LINE_COUNT; i++) { 326 int x1 = GRID_WIDTh / 2 + i * GRID_WIDTh; 327 int y1 = GRID_WIDTh / 2; 328 int x2 = x1; 329 int y2 = y1 + (LINE_COUNT - 1) * GRID_WIDTh; 330 // 画线 331 g.drawLine(x1, y1, x2, y2); 332 } 333 /** 334 * 遍历这个数组 335 */ 336 for (int row = 0; row < LINE_COUNT; row++) { 337 for (int col = 0; col < LINE_COUNT; col++) { 338 // 判断数组当前值,来画棋子 339 switch (chessItems[row][col]) { 340 case WHITE: 341 chessItem(row, col, Color.WHITE, g); 342 //每次画完计算机下完白棋之后,在白棋上面画一个方框 343 chessface(lastpoint,Color.RED, g); 344 break; 345 case BLACK: 346 chessItem(row, col, Color.BLACK, g); 347 break; 348 } 349 repaint(); 350 } 351 } 352 }; 353 354 /** 355 * 清空数组,便于下次下棋 356 */ 357 private void clear() { 358 for (int row = 0; row < LINE_COUNT; row++) { 359 for (int col = 0; col < LINE_COUNT; col++) { 360 // 全部置为0 361 chessItems[row][col] = 0; 362 } 363 } 364 // 重画一遍棋盘 365 repaint(); 366 } 367 368 /** 369 * 用于判断是否已经取胜 370 * 371 * @param row 372 * @param col 373 * @return 374 */ 375 private boolean checkImage(int row, int col) { 376 /** 377 * 判断横行是否win 378 */ 379 StringBuilder stringBuilder = new StringBuilder(); 380 // 记录当前存在字符串中的数据个数 381 int count = 0; 382 for (int i = -4; i <= 4; i++) { 383 int Newcol = col + i; 384 if (Newcol >= 0 && Newcol < LINE_COUNT) { 385 count++; 386 stringBuilder.append(chessItems[row][Newcol]); 387 } 388 } 389 if (stringBuilder.indexOf("11111") >= 0 390 || stringBuilder.indexOf("22222") >= 0) { 391 return true; 392 } else { 393 // 如果当前不能赢,则清空字符串 394 stringBuilder.delete(0, count); 395 count = 0; 396 } 397 /** 398 * 判断竖行是否win 399 */ 400 for (int i = -4; i <= 4; i++) { 401 int Newrow = row + i; 402 if (Newrow >= 0 && Newrow < LINE_COUNT) { 403 count++; 404 stringBuilder.append(chessItems[Newrow][col]); 405 } 406 } 407 if (stringBuilder.indexOf("11111") >= 0 408 || stringBuilder.indexOf("22222") >= 0) { 409 return true; 410 } else { 411 stringBuilder.delete(0, count); 412 count = 0; 413 } 414 /** 415 * 判断负45°是否win 416 */ 417 for (int i = -4; i <= 4; i++) { 418 int Newcol = col + i; 419 int Newrow = row + i; 420 if (Newcol >= 0 && Newcol < LINE_COUNT && Newrow >= 0 421 && Newrow < LINE_COUNT) { 422 count++; 423 stringBuilder.append(chessItems[Newrow][Newcol]); 424 } 425 } 426 if (stringBuilder.indexOf("11111") >= 0 427 || stringBuilder.indexOf("22222") >= 0) { 428 return true; 429 } else { 430 stringBuilder.delete(0, count); 431 count = 0; 432 } 433 /** 434 * 判断正45°是否win 435 */ 436 for (int i = -4; i <= 4; i++) { 437 int Newcol = col + i; 438 int Newrow = row - i; 439 if (Newcol >= 0 && Newcol < LINE_COUNT && Newrow >= 0 440 && Newrow < LINE_COUNT) { 441 count++; 442 stringBuilder.append(chessItems[Newrow][Newcol]); 443 } 444 } 445 if (stringBuilder.indexOf("11111") >= 0 446 || stringBuilder.indexOf("22222") >= 0) { 447 return true; 448 } else { 449 stringBuilder.delete(0, count); 450 count = 0; 451 } 452 return false; 453 } 454 455 // 画棋子 456 public void chessItem(int row, int col, Color color, Graphics graphics) { 457 // x与y分别代表在面板上的位置 458 int x = col * GRID_WIDTh; 459 int y = row * GRID_WIDTh; 460 //判断是白棋还是黑棋 461 Image image=Color.BLACK.equals(color)?blackImage:whiImage; 462 graphics.drawImage(image, x, y, GRID_WIDTh, GRID_WIDTh, this); 463 // graphics.setColor(color); 464 // // 画圆 465 // graphics.fillOval(x, y, GRID_WIDTh, GRID_WIDTh); 466 } 467 /** 468 * 为计算机画白棋定义一个方法,用于在计算机下白棋的棋子上画一个方框,表示是当前的棋子 469 * @param point 470 * @param color 471 * @param graphics 472 */ 473 public void chessface(Point point, Color color, Graphics graphics ){ 474 int x = point.y * GRID_WIDTh; 475 int y = point.x * GRID_WIDTh; 476 graphics.setColor(color); 477 graphics.drawRect(x+GRID_WIDTh/4, y+GRID_WIDTh/4, GRID_WIDTh/2, GRID_WIDTh/2); 478 } 479 } 480 481 public static void main(String[] args) { 482 /** 483 * 使用一个java类来创建一个主类为wuziqijiemianDemo,其中的窗口与棋盘为该主类的内部类 484 */ 485 // 使用类部类的方式创建一个窗口引用对象(方式为 外部类名.内部类名 变量名=new 外部类名().new 内部类名();) 486 wuziqijiemianDemo.Myjframe myjframe = new wuziqijiemianDemo().new Myjframe(); 487 // 设置窗口可见 488 myjframe.setVisible(true); 489 } 490 491 }