java隔山打牛算法_java实现简单网络象棋游戏(2)

2.ChessPanel类:

package internet_chess;

import java.awt.Color;

import java.awt.Font;

import java.awt.Graphics;

import java.awt.Point;

import java.awt.event.MouseAdapter;

import java.awt.event.MouseEvent;

import java.io.IOException;

import java.net.DatagramPacket;

import java.net.DatagramSocket;

import java.net.InetAddress;

import java.net.SocketException;

import java.net.UnknownHostException;

import javax.swing.JOptionPane;

import javax.swing.JPanel;

public class ChessPanel extends JPanel implements Runnable{

private int BLACKCHESS = 1;

private int REDCHESS = 0;//黑棋是1,红旗是0

public Chess chess[] = new Chess[32];//创建了32个棋子对象

private int width = 40;

private int height = 40;

public int Row = 12;

public int Col = 11;//11行10列

public int map[][] = new int [Row][Col];

public int player;//设置当前玩家对象

private boolean isFirst = false;//判断是否是第一次点击的棋子,以此分开两次点击棋子的碰撞矛盾

private int x1,y1,x2,y2;//用来保存第一次第二次选中的坐标的

private boolean flag = true;//用来控制线程的运行

private boolean isPlay = false;

private Chess firstChess = null;

private Chess secondChess = null;//设置第一次点击的棋子和第二次选中的棋子对象

private InetAddress myID;//自己id地址

private InetAddress youID;//目标ID地址

private int sendport;//发送端口

private int receiveport = 8888;//接收端口

public ChessPanel()//构造函数

{

init_map();//初始化棋盘

//给这个面板添加鼠标监听机制

this.addMouseListener(new MouseAdapter()

{

public void mouseClicked(MouseEvent e)

{

if(isPlay == true)//判断是否该本方下棋

{

SelectChess(e.getPoint());//选择要移动的棋子

repaint();

}

}

public void SelectChess(Point pos)

{

int x = pos.x;

int y = pos.y;//获取此时此刻鼠标点击的位置坐标

System.out.println("选择要移动的棋子坐标:x->"+x+" y->"+y);

if(x > 0 && x < (Col-1)*width && y > 0 && y < (Row-1)*height)//判断鼠标是否在合理的范围,不在就直接退出

{

Point point = ReSetID(x,y);

if(isFirst)//判断是否是第一次选中的棋子

{

x1 = point.x;

y1 = point.y;

//判断第一次选中的棋子是不是自己的棋子或者是不是无效棋子,不是就失败

int id = map[x1][y1];

if(id != -1 && chess[id].owner == player)

{

isFirst = false;

firstChess = chess[id];

System.out.println("id->"+id);

}

else//第一次选择的棋子无效

{

JOptionPane.showConfirmDialog(null, "提示", "第一次选棋无效!请重新选择!", JOptionPane.OK_OPTION);

isFirst = true;

}

}

else//第二次选中的棋子

{

x2 = point.x;

y2 = point.y;

int id = map[x2][y2];

if(id != -1 && chess[id].owner != player)//第二次选择了敌方棋子,将敌方棋子保存起来

{

isFirst = true;

secondChess = chess[id];

//开始判断是否可以移动棋子,如果可以就将棋子移动,并发信息给对方我们已经移动的棋子信息

//判断是否可以移动棋子

if(IsMoveChess(firstChess,x2,y2))//可以移动-吃棋

{

int idx1 = map[x1][y1];

map[x1][y1] = -1;

map[x2][y2] = idx1;

chess[id] = null;

firstChess.SetPos(x2, y2);

repaint();

send("move|"+String.valueOf(idx1)+"|"+String.valueOf(Row-1-x2)+"|"+String.valueOf(Col-1-y2)+"|",youID,sendport);

if(id == 0)//吃掉了黑棋将军

{

send("success|红棋赢",youID,sendport);

isPlay = false;

JOptionPane.showConfirmDialog(null, "红棋胜利", "恭喜您,您赢了!", JOptionPane.OK_OPTION);

return;

}

else if(id == 16)//吃掉了红棋大帅

{

send("success|黑棋赢",youID,sendport);

isPlay = false;

JOptionPane.showConfirmDialog(null, "黑棋胜利", "恭喜您,您赢了!", JOptionPane.OK_OPTION);

return;

}

isFirst = true;

isPlay = false;

}

else//表示不能吃棋,重新下棋

{

JOptionPane.showConfirmDialog(null, "提示", "对不起,移动棋子失败,请重新选择目标!", JOptionPane.ERROR_MESSAGE);

isFirst = false;

}

}

else if(id != -1 && chess[id].owner == player)//第二次又选择了自己的棋子,那么就将第二次选择的棋子当做第一次选择的棋子

{

firstChess = chess[id];

x1 = x2;

y1 = y2;

isFirst = false;

}

else//第二次选择的棋子是空,那么就是单纯的移动棋子

{

secondChess = null;

if(IsMoveChess(firstChess,x2,y2))//可以移动-吃棋

{

int idx1 = map[x1][y1];

map[x1][y1] = -1;

map[x2][y2] = idx1;

// chess[id] = null;

firstChess.SetPos(x2, y2);

send("move|"+String.valueOf(idx1)+"|"+String.valueOf(Row-1-x2)+"|"+String.valueOf(Col-1-y2)+"|",youID,sendport);

System.out.println("第二次选中棋子为空:目标-》"+(Row-1-x2)+" "+(Col-1-y2));

repaint();

isFirst = true;

isPlay = false;

}

}

}

}

}

});

}

public boolean IsMoveChess(Chess chess,int x,int y)//判断是否可以移动棋子----移动棋子的规则

{

if(chess.chessName.equals("将") || chess.chessName.equals("帅"))//只能走一步

{

int x0 = chess.point.x;

int y0 = chess.point.y;

if(x >= 8 && x <= 10 && y >= 4 && y <= 6)

{

// int x0 = chess.point.x;

// int y0 = chess.point.y;

if(Math.abs(x - x0) > 1 || Math.abs(y - y0) > 1)

return false;

else if(Math.abs(x - x0)*Math.abs(y - y0) != 0)//不能走斜线

return false;

else

return true;

}

if(this.chess[map[x][y]].chessName.equals("将") || this.chess[map[x][y]].chessName.equals("帅") && (y0 == y))//判断两个将领之间吃棋

{

int min = x < x0? x : x0;

int max = x > x0? x : x0;

for(min = min+1; min < max; min++)

{

if(map[min][y] != -1)

return false;

}

return true;

}

else

return false;

}

else if(chess.chessName.equals("士") || chess.chessName.equals("仕"))//士也不能出田字格,且,士走斜线,每次只走一格

{

if(x >= 8 && x <= 10 && y >= 4 && y <= 6)

{

int x0 = chess.point.x;

int y0 = chess.point.y;

if(Math.abs(x - x0) * Math.abs(y - y0) != 1)

{

return false;

}

else

return true;

}

else//越界

return false;

}

else if(chess.chessName.equals("象") || chess.chessName.equals("相"))//相走田字,且不能过河

{

if(x >= 6 && x != 11 && y >= 1 && y <= 9)

{

int x0 = chess.point.x;

int y0 = chess.point.y;

if(Math.abs(x - x0) * Math.abs(y - y0) != 4)

{

return false;

}

else if(Math.abs(x - x0) == 2 && Math.abs(y - y0) == 2)

{

int xm,ym;//求取中间值,防止中间有值不能走棋

xm = x > x0? x-1:x0-1;

ym = y > y0? y-1:y0-1;

if(map[xm][ym] != -1)//表示中间有棋

return false;

return true;

}

else//防止1*4 == 4的情况出现

return false;

}

else

return false;

}

else if(chess.chessName.equals("马"))//马走日,防止蹩脚的情况出现

{

if(x >= 1 && x <=10 && y >= 1 && y <= 9)

{

int x0 = chess.point.x;

int y0 = chess.point.y;

if(Math.abs(x - x0) * Math.abs(y - y0) == 2)//判断是否走日

{

//判断是否蹩脚

if(Math.abs(y - y0) == 2)

{

if(map[x0][y+1] != -1 && y < y0)//左边

{

return false;

}

if(map[x0][y-1] != -1 && y0 < y)//右边

{

return false;

}

return true;

}

else

{

if(map[x+1][y0] != -1 && x < x0)//上边

{

return false;

}

if(map[x-1][y0] != -1 && x > x0)//下边

{

return false;

}

return true;

}

}

else

return false;

}

else

return false;

}

else if(chess.chessName.equals("车"))//车走直线

{

if(x >= 1 && x <=10 && y >= 1 && y <= 9)

{

int x0 = chess.point.x;

int y0 = chess.point.y;

if(x == x0)//水平移动

{

int i = y < y0 ? y : y0;

int max = y > y0 ? y : y0;

for(i = i+1; i < max; i++)//不判断目标状态,目标状态能否走在外面判断

{

if(map[x][i] != -1)

{

// if(i == max && this.chess[map[x][i]].owner != chess.owner)

// {

// return true;

// }

return false;

}

}

return true;

}

else if(y == y0)//垂直移动

{

int i = x < x0 ? x : x0;

int max = x > x0 ? x : x0;

for(i = i+1; i < max; i++)

{

if(map[i][y] != -1)

{

// if(i == max && this.chess[map[i][y]].owner != chess.owner)

// {

// return true;

// }

return false;

}

}

return true;

}

return false;

}

else

return false;//越界

}

else if(chess.chessName.equals("炮"))//跑隔山打牛,不隔山就走路,水平或者垂直移动

{

if(x >= 1 && x <=10 && y >= 1 && y <= 9)

{

int x0 = chess.point.x;

int y0 = chess.point.y;

int countx = 0;

int county = 0;

if(x == x0)//水平移动

{

int i = y < y0 ? y : y0;

int max = y > y0 ? y : y0;

for(i = i+1; i < max; i++)

{

if(map[x][i] != -1)

{

countx++;

}

}

}

else if(y == y0)//垂直移动

{

int i = x < x0 ? x : x0;

int max = x > x0 ? x : x0;

for(i = i+1; i < max; i++)

{

if(map[i][y] != -1)

{

county++;

}

}

}

if(countx == 1 || county == 1)//说明中间有一个棋

{

// if(this.chess[map[x][y]].owner != chess.owner)

// {

// return true;

// }

// else

// return false;

System.out.println("countx:"+countx);

System.out.println("county:"+county);

return true;

}

else if(countx == 0 && county == 0)//说明中间没有棋

{

if(map[x][y] == -1)//目标没有棋

{

return true;

}

else

return false;

// return true;

}

else

return false;

}

else

return false;//越界

}

else if(chess.chessName.equals("兵") || chess.chessName.equals("卒"))//卒子在自己区域不能退,只能前进,每次只走一步

{

if(x < 7 && x >= 1 && y >= 1 && y <= 9)

{

int x0 = chess.point.x;

int y0 = chess.point.y;

if(x == x0 && Math.abs(y-y0) == 1)//横向只走一步,判断是否在河的这边还是那边

{

//如果是河的这边就不能走横向

if(x == 6)

return false;

else

return true;

}

if(y == y0 && x - x0 == -1)//纵向只走一步,且必须向前走

{

return true;

}

return false;

}

else

return false;

}

return false;

}

public Point ReSetID(int x, int y)//重置id,将id转化成可辨识的坐标信息

{

int posx = (y+height/2)/height;

int posy = (x+width/2)/width;

return new Point(posx,posy);

}

public void init_map()//初始化棋盘

{

for(int i = 0; i < Row; i++)

{

for(int j = 0; j < Col; j++)

{

map[i][j] = -1;//将棋盘初始化为-1,表示没有棋子id

}

}

}

public void paint(Graphics g)//自己画棋盘

{

super.paint(g);

g.clearRect(0,0,this.getWidth(),this.getHeight());

//画棋盘

int a = 1;

int b = 8;

int c = 5;//两军中间的分界线

for(int j = 1; j < Row-1; j++)//画横线

{

g.drawLine(a*width, j*height, (Col-2)*width, j*height);

}

for(int i = 1; i < Col-1; i++)//画竖线

{

g.drawLine(i*width, a*height, i*width, (Row-2)*height);

if(i == 4)

{

g.drawLine(i*width, a*height, (i+2)*width, (a+2)*height);

g.drawLine(i*width, b*height, (i+2)*width, (b+2)*height);

}

if(i == 6)

{

g.drawLine(i*width, a*height, (i-2)*width, (a+2)*height);

g.drawLine(i*width, b*height, (i-2)*width, (b+2)*height);

}

}

g.drawRect(0, 0, (Col-1)*width, (Row-1)*height);

g.setColor(Color.GRAY);

g.fillRect(a*width, c*height,(Col-2-a)*width, height);

g.setFont(new Font("黑体",Font.BOLD,20));

g.setColor(Color.white);

g.drawString("楚 河 汉 界", 3*width, (c+1)*height-10);

g.setColor(Color.black);

//画棋子

for(int i = 0; i < chess.length; i++)

{

if(chess[i] != null)

{

chess[i].paint(g, this);

}

}

if(firstChess != null)

{

firstChess.paintSeclected(g);

}

if(secondChess != null)

{

secondChess.paintSeclected(g);

}

}

public void send(String str,InetAddress ip,int port) //发送数据报

{

DatagramSocket s = null;

try{

s = new DatagramSocket();//创建一个数据报套接字

byte data[] = new byte[100];

data = str.getBytes();

DatagramPacket pocket = new DatagramPacket(data,data.length,ip,port);//将数据报的信息放入自寻址包中,自寻址信息包括数据,数据长度,目标ip地址,目标端口号

s.send(pocket);//发送自寻址包

System.out.println("发送信息:"+str);

}catch(IOException ex)

{

ex.printStackTrace();

}finally

{

if(s != null)

s.close();

}

}

public void startgame(InetAddress ip, int otherport, int myport)//游戏正式开始的起点入口

{

youID = ip;

this.sendport = otherport;

this.receiveport = myport;

try{

myID = InetAddress.getLocalHost();

}catch(UnknownHostException ex)

{

ex.printStackTrace();

}

send("play|",youID,sendport);//发送邀请,等待目标ip的回应----开启一个线程,不断监听端口,检查是否有消息,是否建立连接成功

Thread t = new Thread(this);

t.start();

}

public void FirstPaintChess()//第一次画棋盘---将每个棋盘上的棋子对象摆放完好,设置各自的初始属性

{

//原本把黑棋放上面,红棋放下面,但是为了显示效果,凡是玩家玩,都把玩家的花色放下面

init_map();//如果再玩一局就要先清空棋盘,然后再重置棋子,否则上一局某些位置上面的id会遗留下来

paintChess();

if(player == BLACKCHESS)

{

ReverseChess();

}

repaint();

}

public void ReverseChess()//转置,将坐标改变,以便于下棋者下棋

{

//先改变坐标

// for(int i = 0; i < 32; i++)

// {

// if(chess[i] != null)

// chess[i].ReversePos();

// }

//改变map地图id

for(int i = 0; i < 32; i++)

{

if(chess[i] != null)

{

chess[i].ReversePos();

int xx = chess[i].point.x;

int yy = chess[i].point.y;

map[xx][yy] = i;

}

}

}

public void paintChess()//画棋盘显示,上面黑棋,下面红棋

{

//黑方

chess[0] = new Chess("将",BLACKCHESS,new Point(1,5));

map[1][5] = 0;

chess[1] = new Chess("士",BLACKCHESS,new Point(1,4));

map[1][4] = 1;

chess[2] = new Chess("士",BLACKCHESS,new Point(1,6));

map[1][6] = 2;

chess[3] = new Chess("象",BLACKCHESS,new Point(1,3));

map[1][3] = 3;

chess[4] = new Chess("象",BLACKCHESS,new Point(1,7));

map[1][7] = 4;

chess[5] = new Chess("马",BLACKCHESS,new Point(1,2));

map[1][2] = 5;

chess[6] = new Chess("马",BLACKCHESS,new Point(1,8));

map[1][8] = 6;

chess[7] = new Chess("车",BLACKCHESS,new Point(1,1));

map[1][1] = 7;

chess[8] = new Chess("车",BLACKCHESS,new Point(1,9));

map[1][9] = 8;

chess[9] = new Chess("炮",BLACKCHESS,new Point(3,2));

map[3][2] = 9;

chess[10] = new Chess("炮",BLACKCHESS,new Point(3,8));

map[3][8] = 10;

for(int i = 11,j = 1; i < 16; i++,j+=2)

{

chess[i] = new Chess("卒",BLACKCHESS,new Point(4,j));

map[4][j] = i;

}

//画红棋

chess[16] = new Chess("帅",REDCHESS,new Point(10,5));

map[10][5] = 16;

chess[17] = new Chess("仕",REDCHESS,new Point(10,4));

map[10][4] = 17;

chess[18] = new Chess("仕",REDCHESS,new Point(10,6));

map[10][6] = 18;

chess[19] = new Chess("相",REDCHESS,new Point(10,3));

map[10][3] = 19;

chess[20] = new Chess("相",REDCHESS,new Point(10,7));

map[10][7] = 20;

chess[21] = new Chess("马",REDCHESS,new Point(10,2));

map[10][2] = 21;

chess[22] = new Chess("马",REDCHESS,new Point(10,8));

map[10][8] = 22;

chess[23] = new Chess("车",REDCHESS,new Point(10,1));

map[10][1] = 23;

chess[24] = new Chess("车",REDCHESS,new Point(10,9));

map[10][9] = 24;

chess[25] = new Chess("炮",REDCHESS,new Point(8,2));

map[8][2] = 25;

chess[26] = new Chess("炮",REDCHESS,new Point(8,8));

map[8][8] = 26;

for(int i = 27, j = 1; i < 32; i++, j+=2)

{

chess[i] = new Chess("兵",REDCHESS,new Point(7,j));

map[7][j] = i;

}

}

@Override

public void run()

{

DatagramSocket sock = null;

try {

sock = new DatagramSocket(receiveport);//打开监听窗口

byte data[] = new byte[100];

DatagramPacket pocket = new DatagramPacket(data,data.length);

while(flag)

{

sock.receive(pocket);//接收数据

//读取接收信息

String str = new String(data);

String s[] = new String[6];

s = str.split("\\|");//将数据信息按照|进行分割

if(s[0].equals("play"))//表示此时这个对象是一个被邀请的对象,将被邀请的对象设置为黑棋

{

player = BLACKCHESS;//被邀请者设为黑棋

send("connect|",youID,sendport);

//开始画棋盘

FirstPaintChess();

isPlay = false;//因为是红棋先走,所以黑棋此时不能下棋

}

else if(s[0].equals("connect"))//表示此时的对象是游戏发出者对象,并且已经和被邀请对象建立连接

{

player = REDCHESS;//游戏发出者设为红棋对象

FirstPaintChess();

isPlay = true;//因为此时是红棋,而红旗先走,所以红棋此时可以下棋

}

else if(s[0].equals("lose"))//对方认输

{

JOptionPane.showConfirmDialog(null, "认输", "对方棋手认输!", JOptionPane.OK_OPTION);

isPlay = false;

}

else if(s[0].equals("success"))//对方赢了

{

if(s[1].equals("黑棋赢"))

{

JOptionPane.showConfirmDialog(null, "输了", "黑棋赢了!您输了!", JOptionPane.OK_OPTION);

}

else if(s[1].equals("红棋赢"))

{

JOptionPane.showConfirmDialog(null, "输了", "红棋赢了!您输了!", JOptionPane.OK_OPTION);

}

isPlay = false;

}

else if(s[0].equals("move"))//对方走棋

{

int indx = Integer.parseInt(s[1]);

System.out.println("indx->"+indx);

int posx = Integer.parseInt(s[2]);

System.out.println("posx->"+posx);

int posy = Integer.parseInt(s[3]);

System.out.println("posy->"+posy);

int x = chess[indx].point.x;

int y = chess[indx].point.y;

map[x][y] = -1;

chess[indx].point.x = posx;

chess[indx].point.y = posy;

if(map[posx][posy] != -1)

{

chess[map[posx][posy]] = null;

}

map[posx][posy] = indx;

repaint();

isPlay = true;

}

else if(s[0].equals("quit"))//对方退出

{

JOptionPane.showConfirmDialog(null, "提示", "对方离开,游戏结束!", JOptionPane.OK_OPTION);

isPlay = false;

flag = false;//退出线程

}

}

} catch (SocketException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}finally

{

if(sock != null)

{

sock.close();

}

}

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值