一、简述
上一期讲了五子棋主界面的布局和棋盘绘制,以及按钮就功能的实现,本期来讲解棋子绘制以及棋子连珠判断。
二、棋子绘制
1、坐标获取
为了能够绘制出棋子,首先需要知道鼠标点击时的坐标。因此这里需要使用鼠标监听器中的mouseClicked方法。
public void mouseClicked(MouseEvent e) {
x = e.getX();
y = e.getY();
}
2、坐标处理
接下来是坐标处理,将获取到的鼠标坐标进行变换,目的是为了后续能够保存和画出棋子。
首先是使棋子能够落在网格的交点上,实现思路如下:以第一个交点为圆心,两个交点之间一半的距离为半径划定一个圆形区域,如果鼠标在该区域内点击,就需要将点击的坐标矫正到圆心的坐标。具体实现效果如下:
public void mouseClicked(MouseEvent e) {
//x矫正
//x在前一个交点附近
if ((x - X0) % SIZE > SIZE / 2) {
setX = (x - X0) / SIZE + 1;
} else {
//x在后一个交点附近
setX = (x - X0) / SIZE;
}
//y矫正
if ((y - Y0) % SIZE > SIZE / 2) {
setY = (y - Y0) / SIZE ;
} else {
setY = (y - Y0) / SIZE - 1;
}
}
经过上述处理后,setX和setY将会返回一个以左上角为顶点的一个坐标系数。方便后续将棋子存入二维数组。
3、棋子绘制
接下来是落子的功能。这里需要将坐标转换为窗体的相对坐标
public void mouseClicked(MouseEvent e) {
DropChessX = setX * SIZE + X0;
DropChessY = (setY + 1) * SIZE + Y0;
//使棋子中心正对光标
locationX = DropChessX - CHESS / 2 + 9;
locationY = DropChessY - CHESS / 2 ;
}
创建画笔并画出棋子
public void DrawChess(){
Graphics g = this.getGraphics();
//定义新对象实现画笔功能
setColor1 = new GameMouse();
setColor1.setColor = g;
this.addMouseListener(setColor1);
}
public void mouseClicked(MouseEvent e) {
//设置画笔颜色
setColor.setColor(Color.BLACK);
//绘制棋子
setColor.fillOval(locationX, locationY, CHESS, CHESS);
}
运行效果如下
4、交替下棋
为了能够实现黑白交替下棋的效果,可以使用switch循环实现。而黑棋白棋的绘制和上述一样,将绘制功能的语句放入switch中即可
public void mouseClicked(MouseEvent e) {
//设置循环判断参数
int turn = 0;
x = e.getX();
y = e.getY();
if ((x - X0) % SIZE > SIZE / 2) {
setX = (x - X0) / SIZE + 1;
} else {
setX = (x - X0) / SIZE;
}
if ((y - Y0) % SIZE > SIZE / 2) {
setY = (y - Y0) / SIZE ;
} else {
setY = (y - Y0) / SIZE - 1;
}
//循环判断处理,1为黑棋 , 2为白棋
int NewTurn = turn % 2;
DropChessX = setX * SIZE + X0;
DropChessY = (setY + 1) * SIZE + Y0;
locationX = DropChessX - CHESS / 2 + 9;
locationY = DropChessY - CHESS / 2 ;
switch (NewTurn){
case 0:
setColor.setColor(Color.BLACK);
setColor.fillOval(locationX, locationY, CHESS, CHESS);
turn += 1;
break;
case 1:
setColor.setColor(Color.WHITE);
setColor.fillOval(locationX, locationY, CHESS, CHESS);
turn += 1;
break;
}
}
运行效果如下
三、棋局判断
判断棋局首先要扫描棋盘,并将相同颜色的棋子转化为数值进行累加,最后判断是否相连,因此首先要实现的是将棋局存入二维数组中。
1、棋局存储
首先以棋盘的大小创建一个二维数组,之后在每次落子后将当前棋子的颜色存入数组中的对应位置即可
//定义一个二维数组,LINE为棋盘大小
public static int chessArr[][] = new int[LINE][LINE];
public void mouseClicked(MouseEvent e) {
x = e.getX();
y = e.getY();
if ((x - X0) % SIZE > SIZE / 2) {
setX = (x - X0) / SIZE + 1;
} else {
setX = (x - X0) / SIZE;
}
if ((y - Y0) % SIZE > SIZE / 2) {
setY = (y - Y0) / SIZE ;
} else {
setY = (y - Y0) / SIZE - 1;
}
int NewTurn = turn % 2;
DropChessX = setX * SIZE + X0;
DropChessY = (setY + 1) * SIZE + Y0;
locationX = DropChessX - CHESS / 2 + 9;
locationY = DropChessY - CHESS / 2 ;
switch (NewTurn){
case 0:
setColor.setColor(Color.BLACK);
setColor.fillOval(locationX, locationY, CHESS, CHESS);
//记录棋局
chessArr[setY][setX] = 1; // 1、为黑色 2、为白色
turn += 1;
break;
case 1:
setColor.setColor(Color.WHITE);
setColor.fillOval(locationX, locationY, CHESS, CHESS);
chessArr[setY][setX] = 2; // 1、为黑色 2、为白色
turn += 1;
break;
}
}
2、棋盘扫描
棋盘扫描一共有八个方向,大致思想是从当前棋子开始向该棋子四周进行扫描,并将相同颜色的棋子进行累加。接下来将判断棋局进行分解
水平方向
public int JudgeFlat(int r , int c){//r , c为当前棋子所在的行和列
int count = 1;
//向右
for (int i = c + 1 ; i < arr[r].length; i++) {
if(arr[r][i] == arr[r][c]){
count++;
}else {
break;
}
}
//向左
for(int i = c - 1 ; i >= 0 ; i --){
if(arr[r][i] == arr[r][c]){
count++;
}else {
break;
}
}
return count;
}
竖直方向
public int JudgeVertical(int r , int c){
int count = 1;
//向下
for (int i = r + 1 ; i < arr.length; i++) {
if(arr[r][c] == arr[i][c]){
count ++;
}else {
break;
}
}
//向上
for(int i = r - 1 ; i >= 0 ; i --){
if(arr[r][c] == arr[i][c]){
count ++;
}else {
break;
}
}
return count;
}
对角线
public int JudgeTilt1(int r , int c){
int count = 1;
//右上角
for (int i = c + 1 , a = r - 1 ; i < arr.length && a >= 0 ; i++ , a--) {
if(arr[a][i] == arr[r][c]){
count ++;
}else {
break;
}
}
//左下角
for (int j = r + 1 , b = c - 1 ; j < arr.length && b >= 0 ; j++ , b--) {
if(arr[j][b] == arr[r][c]){
count ++;
}else {
break;
}
}
return count;
}
public int JudgeTilt2(int r , int c){
int count = 1;
//左上角
for(int i = c - 1 , a = r - 1 ; i >= 0 && a >= 0 ; i -- , a --){
if(arr[a][i] == arr[r][c]){
count ++;
}else {
break;
}
}
//右下角
for (int j = c + 1 , b = r + 1 ; j < arr.length && b < arr.length ; j++ , b ++){
if(arr[b][j] == arr[r][c]){
count ++;
}else {
break;
}
}
return count;
}
本期为简单的人人对战的五子棋,下一期讲解如何让电脑下棋