一、团队介绍
二、项目gitee地址
https://gitee.com/immutablelupo/china-chess
三、项目流程图
四、面向对象设计图
1.实现两方兵的行走规则。
2.初始化棋盘,其他棋子的行走规则,棋子的选取等。
3.棋子的坐标。棋子的初始落位。
4.两个客户端之间的信息处理。
五、项目关键代码
兵的移动:一次只能移动一格,判断并是否在敌方半场来确定可移动的方向
public static List<Integer[]> bingMove(Chess chess ){
int i = chess.getI(); int j = chess.getJ(); if(chesses[j][i] != chess){
System.out.println("exp"); } List<Integer[]> list = new ArrayList<>(); if(Main.colorR.equals(chess.getColor())){
if(j<5){
if(j>0){
if(chesses[j-1][i] ==null){
Integer[] integers = {
i,j-1}; list.add(integers); }else{
if(!chesses[j-1][i].getColor().equals(chess.getColor())){
Integer[] integers = {
i,j-1}; list.add(integers); } } } if(i>0){
if(chesses[j][i-1] ==null){
Integer[] integers = {
i-1,j}; list.add(integers); }else{
if(!chesses[j][i-1].getColor().equals(chess.getColor())){
Integer[] integers = {
i-1,j}; list.add(integers); } } } if(i<9){
if(chesses[j][i+1] ==null){
Integer[] integers = {
i+1,j}; list.add(integers); }else{
if(!chesses[j][i+1].getColor().equals(chess.getColor())){
Integer[] integers = {
i+1,j}; list.add(integers); } } } } } return list; }
整个棋盘的实现
public static void drawPlace(GraphicsContext gc) {
gc.setLineWidth(3); gc.strokeLine(girdW / 3, girdH / 3, girdW / 3, canvasH - girdH / 3); gc.strokeLine(girdW / 3 * 2 + girdW * 8, girdH / 3, girdW / 3 * 2 + girdW * 8, canvasH - girdH / 3); gc.strokeLine(girdW / 3, girdH / 3 + girdH * 0, canvasW - girdW / 3, girdH / 3 + girdH * 0); gc.strokeLine(girdW / 3, girdH / 3 * 2 + girdH * 9, canvasW - girdW / 3, girdH / 3 * 2 + girdH * 9); gc.setLineWidth(1); //竖线 for (int i = 0; i < 9; i++) {
//河界要断开 if (i == 0 || i == 8) {
gc.strokeLine(girdW / 2 + girdW * i, girdH / 2, girdW / 2 + girdW * i, canvasH - girdH / 2); } else {
gc.strokeLine(girdW / 2 + girdW * i, girdH / 2, girdW / 2 + girdW * i, canvasH - girdH / 2 - girdH * 5); gc.strokeLine(girdW / 2 + girdW * i, canvasH - girdH / 2 - girdH * 4, girdW / 2 + girdW * i, canvasH - girdH / 2); } } //横线 for (int i = 0; i < 10; i++) {
gc.strokeLine(girdW / 2, girdH / 2 + girdH * i, canvasW - girdW / 2, girdH / 2 + girdH * i); } gc.setTextAlign(TextAlignment.CENTER); gc.setFont(new Font(fontName, fontSize)); gc.fillText("楚河 ", girdW / 2 + girdW * 3, canvasH - girdH * 5 + fontSize / 3); //画帅的x gc.strokeLine(girdW / 2 + girdW * 3, girdH / 2, girdW / 2 + girdW * 5, girdH / 2 + girdH * 2); gc.strokeLine(girdW / 2 + girdW * 3, girdH / 2 + girdH * 2, girdW / 2 + girdW * 5, girdH / 2); //画将x gc.strokeLine(girdW / 2 + girdW * 3, canvasH - girdH / 2, girdW / 2 + girdW * 5, canvasH - girdH / 2 - girdH * 2); gc.strokeLine(girdW / 2 + girdW * 3, canvasH - girdH / 2 - girdH * 2, girdW / 2 + girdW * 5, canvasH - girdH / 2); //画炮的标 gc.strokeLine(girdW / 2 + girdW / 3 * 2, girdH / 2 + girdH * 2 - girdH / 10, girdW / 2 + girdW - girdW / 10, girdH / 2 + girdH * 2 - girdH / 10); gc.strokeLine(girdW / 2 + girdW / 3 * 2, girdH / 2 + girdH * 2 + girdH / 10, girdW / 2 + girdW - girdW / 10, girdH / 2 + girdH * 2 + girdH / 10); gc.strokeLine(girdW / 2 + girdW + girdW / 10, girdH / 2 + girdH * 2 - girdH / 10, girdW / 2 + girdW * 1 + girdW / 3, girdH / 2 + girdH * 2 - girdH / 10); gc.strokeLine(girdW / 2 + girdW + girdW / 10, girdH / 2 + girdH * 2 + girdH / 10, girdW / 2 + girdW * 1 + girdW / 3, girdH / 2 + girdH * 2 + girdH / 10); gc.strokeLine(girdW / 2 + girdW / 3 * 2, girdH / 2 + girdH * 7 - girdH / 10, girdW / 2 + girdW - girdW / 10, girdH / 2 + girdH * 7 - girdH / 10); gc.strokeLine(girdW / 2 + girdW / 3 * 2, girdH / 2 + girdH * 7 + girdH / 10, girdW / 2 + girdW - girdW / 10, girdH / 2 + girdH * 7 + girdH / 10); gc.strokeLine(girdW / 2 + girdW + girdW / 10, girdH / 2 + girdH * 7 - girdH / 10, girdW / 2 + girdW * 1 + girdW / 3, girdH / 2 + girdH * 7 - girdH / 10); gc.strokeLine(girdW / 2 + girdW + girdW / 10, girdH / 2 + girdH * 7 + girdH / 10, girdW / 2 + girdW * 1 + girdW / 3, girdH / 2 + girdH * 7 + girdH / 10); gc.strokeLine(girdW / 2 + girdW / 3 * 2 + girdW * 6, girdH / 2 + girdH * 2 - girdH / 10, girdW / 2 + girdW - girdW / 10 + girdW * 6, girdH / 2 + girdH * 2 - girdH / 10); gc.strokeLine(girdW / 2 + girdW / 3 * 2 + girdW * 6, girdH / 2 + girdH * 2 + girdH / 10, girdW / 2 + girdW - girdW / 10 + girdW * 6, girdH / 2 + girdH * 2 + girdH / 10); gc.strokeLine(girdW / 2 + girdW + girdW / 10 + girdW * 6, girdH / 2 + girdH * 2 - girdH / 10, girdW / 2 + girdW * 1 + girdW / 3 + girdW * 6, girdH / 2 + girdH * 2 - girdH / 10); gc.strokeLine(girdW / 2 + girdW + girdW / 10 + girdW * 6, girdH / 2 + girdH * 2 + girdH / 10, girdW / 2 + girdW * 1 + girdW / 3 + girdW * 6, girdH / 2 + girdH * 2 + girdH / 10); gc.strokeLine(girdW / 2 + girdW / 3 * 2 + girdW * 6, girdH / 2 + girdH * 7 - girdH / 10, girdW / 2 + girdW - girdW / 10 + girdW * 6, girdH / 2 + girdH * 7 - girdH / 10); gc.strokeLine(girdW / 2 + girdW / 3 * 2 + girdW * 6, girdH / 2 + girdH * 7 + girdH / 10, girdW / 2 + girdW - girdW / 10 + girdW * 6, girdH / 2 + girdH * 7 + girdH / 10); gc.strokeLine(girdW / 2 + girdW + girdW / 10 + girdW * 6, girdH / 2 + girdH * 7 - girdH / 10, girdW / 2 + girdW * 1 + girdW / 3 + girdW * 6, girdH / 2 + girdH * 7 - girdH / 10); gc.strokeLine(girdW / 2 + girdW + girdW / 10 + girdW * 6, girdH / 2 + girdH * 7 + girdH / 10, girdW / 2 + girdW * 1 + girdW / 3 + girdW * 6, girdH / 2 + girdH * 7 + girdH / 10); gc.strokeLine(girdW / 2 + girdW * 1 - girdW / 10, girdH / 2 + girdH * 1 + girdH / 3 * 2, girdW / 2 + girdW * 1 - girdW / 10, girdH / 2 + girdH * 2 - girdH / 10); gc.strokeLine(girdW / 2 + girdW * 1 - girdW / 10, girdH / 2 + girdH * 2 + girdH / 10, girdW / 2 + girdW * 1 - girdW / 10, girdH / 2 + girdH * 2 + girdH / 3); gc.strokeLine(girdW / 2 + girdW * 1 + girdW / 10, girdH / 2 + girdH * 1 + girdH / 3 * 2, girdW / 2 + girdW * 1 + girdW / 10, girdH / 2 + girdH * 2 - girdH / 10); gc.strokeLine(girdW / 2 + girdW * 1 + girdW / 10, girdH / 2 + girdH * 2 + girdH / 10, girdW / 2 + girdW * 1 + girdW / 10, girdH / 2 + girdH * 2 + girdH / 3); gc.strokeLine(girdW / 2 + girdW * 1 - girdW / 10, girdH / 2 + girdH * 6 + girdH / 3 * 2, girdW / 2 + girdW * 1 - girdW / 10, girdH / 2 + girdH * 7 - girdH / 10); gc.strokeLine(girdW / 2 + girdW * 1 - girdW / 10, girdH / 2 + girdH * 7 + girdH / 10, girdW / 2 + girdW * 1 - girdW / 10, girdH / 2 + girdH * 7 + girdH / 3); gc.strokeLine(girdW / 2 + girdW * 1 + girdW / 10, girdH / 2 + girdH * 6 + girdH / 3 * 2, girdW / 2 + girdW * 1 + girdW / 10, girdH / 2 + girdH * 7 - girdH / 10); gc.strokeLine(girdW / 2 + girdW * 1 + girdW / 10, girdH / 2 + girdH * 7 + girdH / 10, girdW / 2 + girdW * 1 + girdW / 10, girdH / 2 + girdH * 7 + girdH / 3); gc.strokeLine(girdW / 2 + girdW * 7 - girdW / 10, girdH / 2 + girdH * 1 + girdH / 3 * 2, girdW / 2 + girdW * 7 - girdW / 10, girdH / 2 + girdH * 2 - girdH / 10); gc.strokeLine(girdW / 2 + girdW * 7 - girdW / 10, girdH / 2 + girdH * 2 + girdH / 10, girdW / 2 + girdW * 7 - girdW / 10, girdH / 2 + girdH * 2 + girdH / 3); gc.strokeLine(girdW / 2 + girdW * 7 + girdW / 10, girdH / 2 + girdH * 1 + girdH / 3 * 2, girdW / 2 + girdW * 7 + girdW / 10, girdH / 2 + girdH * 2 - girdH / 10); gc.strokeLine(girdW / 2 + girdW * 7 + girdW / 10, girdH / 2 + girdH * 2 + girdH / 10, girdW / 2 + girdW * 7 + girdW / 10, girdH / 2 + girdH * 2 + girdH / 3); gc.strokeLine(girdW / 2 + girdW * 7 - girdW / 10, girdH / 2 + girdH * 6 + girdH / 3 * 2, girdW / 2 + girdW * 7 - girdW / 10, girdH / 2 + girdH * 7 - girdH / 10); gc.strokeLine(girdW / 2 + girdW * 7 - girdW / 10, girdH / 2 + girdH * 7 + girdH / 10, girdW / 2 + girdW * 7 - girdW / 10, girdH / 2 + girdH * 7 + girdH / 3); gc.strokeLine(girdW / 2 + girdW * 7 + girdW / 10, girdH / 2 + girdH * 6 + girdH / 3 * 2, girdW / 2 + girdW * 7 + girdW / 10, girdH / 2 + girdH * 7 - girdH / 10); gc.strokeLine(girdW / 2 + girdW * 7 + girdW / 10, girdH / 2 + girdH * 7 + girdH / 10, girdW / 2 + girdW * 7 + girdW / 10, girdH / 2 + girdH * 7 + girdH / 3); }
棋子移动时触发的“吃”,和胜利的判定
public void PlayChess(int i,int j, GraphicsContext gc) {
Chess chess = CanvasUtils.clickChess(i*girdW,j*girdH); if(chess != null) {
if(selectChess == null ) {
if(chess.getColor().equals("R")&&roundchange==0||chess.getColor().equals("B")&&roundchange==1) {
{
if(roundchange==0) {
roundchange = roundchange + 1; } else if(roundchange==1) {
roundchange = roundchange - 1; } System.out.println(roundchange); CanvasUtils.selectChess(chess, gc); } } } else {
CanvasUtils.moveChess(i, j, gc);//吃棋子 if(Tool!=null) {
if (Tool.chessName.equals("帥") || Tool.chessName.equals("將")) System.out.println("win!"); } } } else {
CanvasUtils.moveChess(i, j, gc);//移动到没有棋子的地方 if(Tool!=null) {
if (Tool.chessName.equals("帥") || Tool.chessName.equals("將")) System.out.println("win!"); } } }
服务器,读取并转发客户端送来的信息。
public class Server {
ServerSocket serverSocket = null; static Map<Integer, Socket> map = new HashMap<Integer, Socket>(); public static int i=1; public static int flag3=0; public static BufferedWriter bwa = null; public static BufferedWriter bwb = null; public void socket() throws IOException {
try {
ServerSocket ss = new ServerSocket(8887); System.out.println("启动服务器...."); //客户端1 ExecutorService executor= Executors.newFixedThreadPool(1); CompletableFuture<String> future2 = CompletableFuture.supplyAsync(()-> {
try {
System.out.println("异步启动:"); try {
while(true) {
Socket s1 = ss.accept(); InetAddress inetAddress=s1.getInetAddress(); System.out.println("客户端:" +"2:"+ s1.getInetAddress().getLocalHost() + "已连接到服务器"); flag3++; i++; System.out.println(i); if (s1 != null) {
try {
while(true) {
// 3.获取socket通道的输入流(输入流的读取方式为一行一行的读取方式 ----> readLine()) // 4.获取通道的输入流(也是一行一行的写出 BufferedWriter ->newLine()) // 当用户“发送”按钮的时候才会,写出数据 BufferedReader br1 = new BufferedReader(new InputStreamReader(s1.getInputStream())); Server.bwb = new BufferedWriter(new OutputStreamWriter(s1.getOutputStream())); if(flag3==2) {
String line1="双方棋手已就位,请红色方先开始棋局"; bwa.write(line1); System.out.println("服务端发送信息:"+line1); bwa.newLine(); // 换行 bwa.flush(); // bwb.write(line1); System.out.println("服务端发送信息:"+line1); bwb.newLine(); // 换行 bwb.flush(); // } String line = null; while ((line = br1.readLine()) != null) {
System.out.println("客户端发送信息:" + line); // 将读取的数据拼接到文本域中显示 if (line.contains("#")) {
bwa.write(line); System.out.println("服务端发送信息:"+line); bwa.newLine(); // 换行 bwa.flush(); // } } System.out.println(line); } } catch(Exception e){
e.printStackTrace(); } } } } catch (IOException e) {
e.printStackTrace(); } Thread.sleep(5000); return "finish"; } catch (InterruptedException e) {
System.err.println("错误!"); return "wrong!"; } },executor); //客户端2 while (true) {
Socket s2 = ss.accept(); InetAddress inetAddress = s2.getInetAddress(); System.out.println("客户端:" + "1:" + s2.getInetAddress().getLocalHost() + "已连接到服务器"); flag3++; if (s2 != null) {
try {
while (true) {
// 3.获取socket通道的输入流(输入流的读取方式为一行一行的读取方式 ----> readLine()) // 4.获取通道的输入流(也是一行一行的写出 BufferedWriter ->newLine()) // 当用户“发送”按钮的时候才会,写出数据 BufferedReader br1 = new BufferedReader(new InputStreamReader(s2.getInputStream())); Server.bwa = new BufferedWriter(new OutputStreamWriter(s2.getOutputStream())); if(flag3==2) {
String line1="双方棋手已就位,请红色方开始棋局"; bwa.write(line1); System.out.println("服务端发送信息:"+line1); bwa.newLine(); // 换行 bwa.flush(); // bwb.write(line1); System.out.println("服务端发送信息:"+line1); bwb.newLine(); // 换行 bwb.flush(); // } String line = null; while ((line = br1.readLine()) != null) {
System.out.println("客户端发送信息:" + line); // 将读取的数据拼接到文本域中显示 bwb.write(line); System.out.println("服务端发送信息:"+line); bwb.newLine(); // 换行 bwb.flush(); // } System.out.println(line); } } catch (Exception e) {
e.printStackTrace(); } } } } catch (IOException e) {
e.printStackTrace(); } } public static void main(String[] args) throws IOException {
new Server().socket(); } }
七、客户端发送信息
public void sendServer(String msg) {
try {
bw1.write(msg); bw1.newLine(); // 换行 bw1.flush(); // } catch (IOException e) {
e.printStackTrace(); } }
八、客户端接收信息
btn.setOnAction(actionEvent -> {
ExecutorService executor= Executors.newFixedThreadPool(1); CompletableFuture<String> future2 = CompletableFuture.supplyAsync(()-> {
try {
try{
/*客户端 TCP协议*/ // 1.创建一个客户端的套接字(尝试连接) Socket socket = new Socket("127.0.0.1",8887); // 2.获取socket通道的输入流 BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); bw1 = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); String line = null; while((line = br.readLine()) !=null) {
textarea.appendText("服务器发送信息:"+line); if(line.contains("#")) {
String ti=String.valueOf(line.charAt(1)); String tj=String.valueOf(line.charAt(2)); String ta=String.valueOf(line.charAt(3)); String tb=String.valueOf(line.charAt(4)); System.out.println(ti+tj+ta+tb); updateChess(Integer.parseInt(ta),Integer.parseInt(tb),Integer.parseInt(ti),Integer.parseInt(tj),gc); textarea.appendText("对方落子:"+line.substring(1,3)+"-->"+line.substring(3,5)); stop=0; if(roundchange==1) {
roundchange = roundchange - 1; } else if(roundchange==0) {
roundchange=roundchange+1; } } if(line.contains("@")) {
textarea.appendText(line); } } System.out.println(line); // 3. 获取输出流 // 4.关闭流 socket.close(); // } catch(Exception e){
e.printStackTrace(); } Thread.sleep(5000); return "finish"; } catch (InterruptedException e) {
System.err.println("错误!"); return "wrong!"; } },executor); });
六、运行截图
单机版的运行
网络对战版
两者连接
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ji-chu/87248.html