安阳工学院
JAVA课程综合项目报告
20##年12月
安阳工学院计算机学院制
目 录
一、系统目标... 2
二、系统设计思路... 2
三、系统详细设计... 2
四、系统实现... 9
五、系统设计总结... 12
六、参考文献... 12
一、 系统目标
1、主要是介绍开发五子棋的整个过程,体现流程设计与类设计的基本方法,示范了数组的使用,使用了分支结构与循环结构的流程控制
2、通过课程设计把课堂上讲的内容融会贯通,学会设计程序、开发应软件、开发系统软件等各项工作。
3、通过实习掌握语言的语法结构,理解类和对象的概念,准确的使用各种数据类型,对面向对象中的继承和多态的概念要理解、会使用,在程序中提高代码的重用性,使设计的程序结构清晰、易于维护。
二、系统设计思路
1、获取棋盘 设计一个11╳11围棋棋盘,由两玩家交替进行对战,并可以实现以下功能。五子棋的规则为:
2、下棋方法 两人分别执黑白两色棋子。轮流在棋盘上选择一个无子的交叉点落子,无子的交叉点又被称为空点。
3、输赢判断 每次下完一颗棋子,就通过程序从横、竖、斜各个方向扫描棋盘,如果在某个方向中,有同种颜色的棋子达到五连子,则此颜色的玩家为赢。如果没有相同颜色的棋子达到五连子,则继续游戏。
三、系统详细设计
3.1程序流程图
3.2创建棋盘类,绘制棋盘的样式
main方法创建了ChessFrame类的一个实例对象,并启动屏幕显示显示该实例对象。
public static void main(String argc[]) {
myframe f = new myframe();
}
构造五子棋的主窗体:
class myframe extends Frame implements WindowListener {
mypanel panel;
myframe() {
setLayout(null);
panel = new mypanel();
add(panel);
panel.setBounds(0, 23, 360, 360);
setTitle("单人版五子棋42阮营营");
setBounds(200, 200, 360, 383);
setVisible(true);
addWindowListener(this);
初始化棋盘:
mypanel() {
Is_Black_True = true;
for (int i = 0; i < 11; i++) {
for (int j = 0; j < 11; j++) {
chess[i][j] = 0;
}
}
规定棋盘的宽度、高度、棋盘的模式:
setBounds(0, 0,360 ,360);
setVisible(true);
窗体响应事件:
public void windowDeactivated(WindowEvent e) {
}
public void windowActivated(WindowEvent e) {
}
public void windowOpened(WindowEvent e) {
}
public void windowClosed(WindowEvent e) {
}
public void windowIconified(WindowEvent e) {
}
public void windowDeiconified(WindowEvent e) {
}
3.3编写一个功能判断落子的位置及画出相应的黑白棋子
定义鼠标响应事件,判断该坐标位置是否可下棋子:
public void mousePressed(MouseEvent e)
判断该坐标位置是否可下棋子:
void Drawchess(Graphics g) {
for (int i = 0; i < 11; i++) {
for (int j = 0; j < 11; j++) {
if (chess[i][j] == 1) {
g.setColor(Color.BLACK);
g.fillOval((i + 1) * 30 - 8, (j + 1) * 30 - 8, 16, 16);
}
if (chess[i][j] == 2) {
g.setColor(Color.WHITE);
g.fillOval((i + 1) * 30 - 8, (j + 1) * 30 - 8, 16, 16);
3.4判断输赢
void Justisewiner() {
int black_count = 0;
int white_count = 0;
int i = 0;
for (i = 0; i < 11; i++)// 横向判断
{
for (int j = 0; j < 11; j++) {
if (chess[i][j] == 1) {
black_count++;
if (black_count == 5) {
JOptionPane.showMessageDialog(this, "黑棋胜利");
Clear_Chess();
return;
}
} else {
black_count = 0;
}
if (chess[i][j] == 2) {
white_count++;
if (white_count == 5) {
JOptionPane.showMessageDialog(this, "白棋胜利");
Clear_Chess();
return;
}
} else {
white_count = 0;
}
}
}
for (i = 0; i < 11; i++)// 竖向判断
{
for (int j = 0; j < 11; j++) {
if (chess[j][i] == 1) {
black_count++;
if (black_count == 5) {
JOptionPane.showMessageDialog(this, "黑棋胜利");
Clear_Chess();
return;
}
} else {
black_count = 0;
}
if (chess[j][i] == 2) {
white_count++;
if (white_count == 5) {
JOptionPane.showMessageDialog(this, "白棋胜利");
Clear_Chess();
return;
}
} else {
white_count = 0;
}
}
}
for (i = 0; i < 7; i++)// 左向右斜判断
{
for (int j = 0; j < 7; j++) {
for (int k = 0; k < 5; k++) {
if (chess[i + k][j + k] == 1) {
black_count++;
if (black_count == 5) {
JOptionPane.showMessageDialog(this, "黑棋胜利");
Clear_Chess();
return;
}
} else {
black_count = 0;
}
if (chess[i + k][j + k] == 2) {
white_count++;
if (white_count == 5) {
JOptionPane.showMessageDialog(this, "白棋胜利");
Clear_Chess();
return;
}
} else {
white_count = 0;
}
}
}
}
for (i = 4; i < 11; i++)// 右向左斜判断
{
for (int j = 6; j >= 0; j--) {
for (int k = 0; k < 5; k++) {
if (chess[i - k][j + k] == 1) {
black_count++;
if (black_count == 5) {
JOptionPane.showMessageDialog(this, "黑棋胜利");
Clear_Chess();
return;
}
} else {
black_count = 0;
}
if (chess[i - k][j + k] == 2) {
white_count++;
if (white_count == 5) {
JOptionPane.showMessageDialog(this, "白棋胜利");
Clear_Chess();
return;
}
} else {
white_count = 0;
}
}
}
}
}
四、系统实现
4.1编译运行源程序
4.2获取棋盘
4.3下棋
4.4判断输赢
1.黑棋胜
2.白棋胜
五、系统设计总结
这个课设题对我来说有一定的挑战性,因为我自己也不知道自己到底学到了一个什么样的境界。但可以肯定,这个课设题的要求绝对在我的能力范围以上。之所以选择这个题目是想逼着自己去查更多的资料,学到更多的东西。结果也确实是这样的,我在这次课设中学到了不少东西,也理解了许多原来不理解的东西。尽管这个系统做的并不是那么的完善。
对于Java中的引用,初始化类等,开始我并不是非常的理解,知道就这么做就能实现相应的功能了,并没有很深刻的去理解它为什么要这么做。但是真正的要用Java去做一个东西不理解它是不行的,而且其间这课设涉及到了Java 中的绝大多数的知识点,如Java图形用户界面设计、Java的异常处理机制、Java中的多线程程序设计、Java输入输出流,要应用这些东西更要求我去好好理解Java的这些规则。但是理解了Java的规则要把这个课设做好也不是那么容易,最难的部分是如何实现各个功能的划分和类的通讯问题。我在这方面就遇到了不少的问题。
总结这次课设,我还是收获不少。虽然界面也不是很美观,有点功能间的连接做的也不是特别的好,但是我能认识到自己的不足,并且在跟同学的交流中也学到了一些他们的设计思路,也知道今后要加强哪些方面的知识。
六、参考文献
1. 吴其庆编著.Java程序设计实例教程.北京:冶金工业出版社
2. 柳西玲.许斌编著.Java语言应用开发基础.北京:清华大学出版社
3. (美)CayS.Horsttmann Gary Cornell JAVA核心技术卷i:基础知识(原书第七版): 机械工业出版社
4.丁振凡 Java 语言实用教程 :北京邮电大学出版社
第二篇:java程序设计五子棋
package FiveChess;
import java.awt.Color;
import java.awt.Graphics;
public class Chess {
int id;
int chess_x;
int chess_y;
int state;
int radius=13;
public Chess(){}
public Chess(int id,int chess_x,int chess_y,int state){ this.id=id;
this.chess_x=chess_x;
this.chess_y=chess_y;
this.state=state;
}
public int getChess_x() {
return chess_x;
}
public void setChess_x(int chess_x) {
this.chess_x = chess_x;
}
public int getChess_y() {
return chess_y;
}
public void setChess_y(int chess_y) {
this.chess_y = chess_y;
}
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public void drawChess(Graphics g){
Color color=null;
if(state==1){
color=new Color(255,255,255);
g.setColor(color);
g.fillOval(chess_x*30-radius, chess_y*30-radius, radius*2, radius*2); }else if(state==-1){
color=new Color(0,0,0);
g.setColor(color);
g.fillOval(chess_x*30-radius, chess_y*30-radius, radius*2, radius*2); }
}
}
package FiveChess;
import java.awt.Graphics;
public class ChessBoard {
int [][]board=new int[16][16];
public ChessBoard(){
initialBoard();
}
public void initialBoard(){
for(int i=0;i<board.length;i++){
for(int j=0;j<board[i].length;j++){
board[i][j]=0;//0无棋1白棋-1黑棋
}
}
}
public void draw(Graphics g){
g.drawLine(25, 25, 455, 25);
g.drawLine(455, 25, 455, 455);
g.drawLine(25, 455, 455, 455);
g.drawLine(25, 25, 25, 455);
int i=1,j=1;
while(i<board.length){
g.drawLine(i*30, 30, i*30, 15*30);
i++;
}
while(j<board.length){
g.drawLine(30,j*30 , 15*30, j*30);
j++;
}
}
public int getState(int x,int y){
if(x>0&y>0&x<16&y<16) return board[x][y];
else return -2;
}
public void setState(int x,int y,int state){
board[x][y]=state;
}
}
package FiveChess;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.TextArea;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.sql.Time;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.JTextField;
import javax.swing.border.Border;
public class ChessServer extends JFrame implements ActionListener{ public static final int frame_width=35;//窗体的宽度 public static final int frame_height=27;//窗体的高度
public static final int frame_opration=10;//操作区域的宽度
public static final int block_width=20;//单位宽度 public static final int block_height=20;//单位高度 ServerWar jpz=new ServerWar(this);//创建服务器端主面板 JMenuBar menubar=new JMenuBar();//创建菜单条 JMenu fileMenu=new JMenu("文件"); JMenuItem one = new JMenuItem("单人游戏"); JMenuItem two =new JMenuItem("双人游戏"); JMenuItem exit=new JMenuItem("退出"); JPanel jpy=new JPanel();//创建操作区的面板 JLabel jlPort=new JLabel("端口号");//创建提示用户输入端口号的标签 JTextField jtfPort=new JTextField("9999");//创建用于输入端口号的文本框,默认是9999 JLabel jlNickName=new JLabel("昵 称");//创建用于提示输入昵称的标签 JTextField jtfNickName=new JTextField("Player2");//创建用于输入昵称的文本框 JButton jbNew=new JButton("建主");//创建"建主","停止","开始"三个动作按钮 JButton jbStop=new JButton("停止"); JButton jbStart=new JButton("开始"); JButton jbSend=new JButton("发送"); TextArea jaChat=new TextArea("",5000,1,TextArea.SCROLLBARS_VERTICAL_ONLY); int textIndex=0; JTextField jtfMessage=new JTextField("你好"); JSplitPane jsp=new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,jpz,jpy);//创建JSplitPane ServerSocket ss;//声明ServerSocket引用 ServerThread st;//声明服务器线程 ServerAgentThread sat;//声明服务器代理线程引用 public ChessServer(){ this.addComponent();//初始化窗体,将控件添加到窗体中 this.addListener();//为相应控件注册监听器 this.initialFrame();//初始化窗体 jpz.setFocusable(true); jpz.requestFocus(true);//使左边面板获得焦点 } public void addComponent(){//添加控件 的方法 jpy.setLayout(null);//设为空布局 jlPort.setBounds(10,20,40,25); jpy.add(jlPort);//添加"端口号"标签 jtfPort.setBounds(55,20,100,25); jpy.add(jtfPort);//添加输入端口号的文本框
jlNickName.setBounds(10,50,40,25); jpy.add(jlNickName);//添加"昵称"标签 jtfNickName.setBounds(55,50,100,25); jpy.add(jtfNickName);//添加输入昵称的文本框 jbNew.setBounds(20,85,60,20); jpy.add(jbNew);//添加"建主"按钮 jbStop.setBounds(100,85,60,20); jpy.add(jbStop);//添加"停止"按钮 jbStart.setBounds(20,120,140,30); jpy.add(jbStart);//添加"开始"按钮 jaChat.setBounds(10, 230, 160, 205); jaChat.setForeground(Color.blue); jaChat.setEditable(false); jpy.add(jaChat); jtfMessage.setBounds(10, 440, 100, 25); jpy.add(jtfMessage); jbSend.setBounds(120, 440, 60, 20); jpy.add(jbSend); jsp.setDividerLocation((frame_width-frame_opration)*block_width); jsp.setDividerSize(4);//设置JSplitPane分割线的位置及宽度 fileMenu.add(one); fileMenu.add(two); fileMenu.addSeparator(); fileMenu.add(exit); fileMenu.setBounds(0, 0, 20, 20); menubar.add(fileMenu); this.add(menubar,BorderLayout.NORTH); this.add(jsp);//添加jsp } public void addListener(){//为控件注册监听器 jbNew.addActionListener(this);//为"建主"按钮注册监听器 jbStop.addActionListener(this);//为"停止"按钮注册监听器 jbStart.addActionListener(this);//为"开始"按钮注册监听器 one.addActionListener(this); two.addActionListener(this); exit.addActionListener(this); jbSend.addActionListener(this); } public void actionPerformed(ActionEvent e){ if(e.getSource()==this.jbNew){//当按下"建主"按钮时 int port=0; try{//获得用户输入的端口号 port=Integer.parseInt(this.jtfPort.getText().trim()); }
} catch(Exception ee){//如果不是数字则给出提示 JOptionPane.showMessageDialog(this,"端口号只能是整数","错误", JOptionPane.ERROR_MESSAGE); return; } if(port>65535||port<0){//判断端口号是否在有效范围内 JOptionPane.showMessageDialog(this,"端口号只能是0-65535的整数", "错误",JOptionPane.ERROR_MESSAGE); return; } try{ ss=new ServerSocket(port);//创建ServerSocket st=new ServerThread(this,ss);//创建服务器线程 st.start();//启动服务器线程 JOptionPane.showMessageDialog(this,"服务器启动成功","提示", JOptionPane.INFORMATION_MESSAGE);//给出成功的提示 this.setState(false);//设置窗体状态 this.jbStart.setEnabled(false); } catch(Exception ee){//启动失败 JOptionPane.showMessageDialog(this,"服务器启动失败","提示", JOptionPane.INFORMATION_MESSAGE); } else if(e.getSource()==this.jbStop){//当单击"停止"按钮时 try{ if(sat!=null){//代理线程不为空,则向客户端发出离开的消息 sat.dout.writeUTF("<#ServerDown#>"); sat.setFlag(false);//终止代理线程 } st.setFlag(false);//终止服务器线程 ss.close();//关闭连接 } catch(IOException ee){ee.printStackTrace();} this.setState(true);//设置窗体状态 jpz.setGameState(false);//设置游戏状态 } else if(e.getSource()==this.jbStart){//当单击"开始"按钮时 if(jpz.ready==false){ JOptionPane.showMessageDialog(this,"客户端还未准备", "提示",JOptionPane.INFORMATION_MESSAGE); }else{ int result=JOptionPane.showConfirmDialog(this,"是否开始新游戏?", "提示",JOptionPane.YES_NO_OPTION);
if(result==0){ try{sat.dout.writeUTF("<#Start#>");} catch(IOException ee){ee.printStackTrace();} jpz.setGameState(true);//开始游戏 jpz.setChess_id(0); jpz.chess=new Chess[255]; jpz.chess[0]=new Chess(0,0,0,0); jpz.repaint(); } } } else if(e.getSource()==this.one){
//与计算机游戏
jtfPort.setEnabled(false);
jtfNickName.setEnabled(false);
jbNew.setEnabled(false);
jbStop.setEnabled(false);
jbStart.setEnabled(false);
jpz.setGameState(false);
jpz.setOneGameState(true);
}
else if(e.getSource()==this.two){
setState(true);
jpz.setOneGameState(false);
}
else if(e.getSource()==this.exit){
int result=JOptionPane.showConfirmDialog(this,"是否要退出?",
"提示",JOptionPane.YES_NO_OPTION);
if(result==0){
System.exit(0);
}
}
else if(e.getSource()==this.jbSend){
if(!jtfMessage.getText().trim().equals("")){
Time time=new Time(System.currentTimeMillis());
String message=jtfNickName.getText()+" "+time.getHours()+":"+time.getMinutes()+":"+time.getSeconds()+"\n"+jtfMessage.getText()+"\n";
try {
sat.dout.writeUTF("<#ServerMessage#>"+message);
} catch (IOException e1) {
e1.printStackTrace();
}
jtfMessage.setText("");
// jaChat.insert(message, textIndex); textIndex+=message.length(); }else{ String s="不能发送空消息。\n"; jaChat.insert(s,textIndex); textIndex+=s.length(); } } jpz.requestFocus(true); } public void initialFrame(){//初始化窗体的方法 this.setState(true); Image image=new ImageIcon("ico.gif").getImage();
this.setIconImage(image);//设置图标
this.setTitle("FiveChess--Server");//设置标题
this.setResizable(false);
Dimension screenSize = //获得屏幕尺寸
Toolkit.getDefaultToolkit().getScreenSize();
int centerX=screenSize.width/2;//计算屏幕的中心坐标
int centerY=screenSize.height/2;
int width=frame_width*block_width;//计算窗口的高度和宽度
int height=frame_height*block_height;
this.setBounds(centerX-width/2,centerY-height/2-30,width,height);//使窗体居中显示 this.addWindowListener(
new WindowAdapter(){
public void windowClosing(WindowEvent e){
} } if(st==null){//服务器线程为空,则直接退出 System.exit(0); return; } try{ if(sat!=null){//代理线程非空,向客户端发送离开的消息 sat.dout.writeUTF("<#ServerDown#>"); sat.setFlag(false);//终止代理线程 } st.setFlag(false);//终止服务器线程 ss.close();//关闭连接 } catch(IOException ee){ee.printStackTrace();} System.exit(0); //
);
this.setVisible(true);
}
public void setState(boolean state){//设置窗体状态的方法 jtfPort.setEnabled(state);
jtfNickName.setEnabled(state);
jbNew.setEnabled(state);
jbStop.setEnabled(!state);
jbStart.setEnabled(!state);
jaChat.setEnabled(!state);
jbSend.setEnabled(!state);
jtfMessage.setEnabled(!state);
}
public static void main(String[] args) {
new ChessServer();
}
}
package FiveChess;
import java.awt.Color;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;
import javax.swing.JOptionPane;
public class ClientAgentThread extends Thread {
ChessClient father;
Socket sc;//声明Socket引用
boolean flag=true;//控制该线程的标志位
DataInputStream din;//声明数据输入流
DataOutputStream dout;//声明数据输出流
public ClientAgentThread(ChessClient father,Socket sc){//构造器 this.father=father;
this.sc=sc;
try{//创建输入输出流
din=new DataInputStream(sc.getInputStream());
dout=new DataOutputStream(sc.getOutputStream());
String name=father.jtfNickName.getText().trim();//获得昵称
dout.writeUTF("<#NICK_NAME#>"+name);//将昵称传送给服务器 } catch(Exception e){e.printStackTrace();} } public void run(){ String msg1=""; while(flag){ try{ String msg=din.readUTF().trim();//接收客户端信息 if(msg1.equals(msg)) msg=""; if(msg.startsWith("<#ServerDown#>")){//收到服务器离开的信息 father.jpz.setGameState(false);//设置jpz状态为,停止游戏 this.flag=false;//设置该线程标志位,停止该线程 this.sc.close();//关闭Socket father.cat=null;//将主窗体的代理线程设为空 JOptionPane.showMessageDialog(father,"主机离开了!!!","提示", JOptionPane.INFORMATION_MESSAGE);//弹出提示对话框 father.setState(true);//设置客户端主窗体的状态 }else if(msg.startsWith("<#ServerWin#>")){ father.jpz.setGameState(false); father.jbReady.setBackground(Color.white); JOptionPane.showMessageDialog(father,"黑棋胜!!!","提示", JOptionPane.INFORMATION_MESSAGE);//弹出提示对话框 msg1=msg; } else if(msg.startsWith("<#Start#>")) { father.jpz.setGameState(true);//设置jpz状态位,开始游戏 father.jpz.setChess_id(0); father.jpz.chess=new Chess[255]; father.jpz.chess[0]=new Chess(0,0,0,0); father.jpz.repaint(); msg1=msg; } else if(msg.startsWith("<#ServerChess#>")){//收到服务器下子的消息 String info=msg.substring(15);//获得有用信息 String[] detail=info.split("/");//分解信息 int chess_id=new Integer(detail[0]); int chess_x=new Integer(detail[1]); int chess_y=new Integer(detail[2]); int state=new Integer(detail[3]); father.jpz.mouse.addChess(chess_id, chess_x, chess_y, state); father.jpz.setChess_id(chess_id); father.jpz.repaint();
msg1=msg;
}
else if(msg.startsWith("<#ServerMessage#>")){ String info=msg.substring(17)+"\n";
father.jaChat.insert(info, father.textIndex); father.textIndex+=info.length(); msg1=msg;
}
}catch(Exception e){e.printStackTrace();} }
}
public void setFlag(boolean flag){this.flag=flag;}
}
package FiveChess;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class ClientWar extends JPanel {
ChessBoard chessBoard =new ChessBoard();
Chess chess[]=new Chess[255];
boolean gameState=false;
boolean oneGameState=true;
int clientChessType=1;
int Chess_id=0;
// CPaintThread cpt;
ChessClient father;
mouseListener mouse=new mouseListener();
public ClientWar(ChessClient father){
this.father=father;
// cpt=new CPaintThread(father);//创建绘制线程
// cpt.start();//启动该绘制线程
// setBackground(Color.LIGHT_GRAY);
addMouseListener(mouse);
chess[0]=new Chess(0,0,0,0);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
chessBoard.draw(g);
int i=0;
while(i<=Chess_id){
draw(g,chess[i]);
i++;
}
}
public void draw(Graphics g,Chess ch){
ch.drawChess(g);
}
class mouseListener extends MouseAdapter {
public void mouseReleased(MouseEvent e){
if(gameState==true&&chess[Chess_id].state!=clientChessType){
int x=e.getX();
int y=e.getY();
if(x%30<=15) x=x/30;
else if(x%30>15) x=x/30+1;
if(y%30<=15) y=y/30;
else if(y%30>15) y=y/30+1;
if(x>0&&y>0&&x<16&&y<16&&chessBoard.getState(x, y)==0){
Chess_id++;
addChess(Chess_id,x,y,clientChessType);
chessBoard.setState(x, y, clientChessType);
//验证是否构成五子
if(isFive(x,y)){
this.sendMsg("<#ClientWin#>");
setGameState(false);
father.jbReady.setBackground(Color.white);
JOptionPane.showMessageDialog(father,"白棋胜!!!","提示", JOptionPane.INFORMATION_MESSAGE);//弹出提示对话框
}
repaint();
}
}
else if(gameState==true&&oneGameState==true){
JOptionPane.showMessageDialog(father,"发生错误,自动退出!", "错误",JOptionPane.ERROR); System.exit(0); } else if(oneGameState==true){ //单人游戏过程 } else if(gameState==false&&oneGameState==false) JOptionPane.showMessageDialog(father,"请先开始游戏!",
"提示",JOptionPane.INFORMATION_MESSAGE);
}
public boolean isFive(int chess_x,int chess_y){
int level=1;
int x=chess_x;
int y=chess_y;
while(x>1&&chessBoard.board[x-1][y]==clientChessType){
level++;
if(level==5){
return true;
}
x--;
}
x=chess_x;
y=chess_y;
while(x<15&&chessBoard.board[x+1][y]==clientChessType){
level++;
if(level==5){
return true;
}
x++;
}
int apeak=1;
x=chess_x;
y=chess_y;
if(y>1){
while(y>1&&chessBoard.board[x][y-1]==clientChessType){
apeak++;
if(apeak==5){
return true;
}
y--;
}
}
x=chess_x; y=chess_y; while(y<15&&chessBoard.board[x][y+1]==clientChessType){ apeak++; if(apeak==5){ return true; } y++; } int bias1=1; x=chess_x; y=chess_y; while(x>1&&y>1&&chessBoard.board[x-1][y-1]==clientChessType){ bias1++; if(bias1==5){ return true; } x--;y--; } x=chess_x; y=chess_y; while(x<15&&y<15&&chessBoard.board[x+1][y+1]==clientChessType){ bias1++; if(bias1==5){ return true; } x++;y++; } int bias2=1; x=chess_x; y=chess_y; while(x<15&&y>1&&chessBoard.board[x+1][y-1]==clientChessType){ bias2++; if(bias2==5){ return true; } x++;y--; } x=chess_x; y=chess_y; while(x>1&&y<15&&chessBoard.board[x-1][y+1]==clientChessType){ bias2++; if(bias2==5){ return true;
}
x--;y++;
}
return false;
}
public void addChess(int id,int x,int y,int state){
Chess clientChess=new Chess(id,x,y,state);
// m_chess.put(id, clientChess);
chess[id]=clientChess;
this.sendMsg("<#ClientChess#>"+clientChess.getId()+"/"+clientChess.getChess_x()+"/"+clientChess.getChess_y()+
} "/"+clientChess.getState());//将客户棋子的状态发送给服务期 public void sendMsg(String msg){//用于向服务器发送消息的方法 try{
father.cat.dout.writeUTF(msg);//发送消息
}
catch(IOException e){e.printStackTrace();}
}
}
public void setGameState(boolean gameState){
this.gameState=gameState;
}
public void setChess_id(int chess_id) {
Chess_id = chess_id;
}
public int getClientChessType() {
return clientChessType;
}
public void setClientChessType(int clientChessType) {
this.clientChessType = clientChessType;
}
public void setOneGameState(boolean oneGameState) {
this.oneGameState = oneGameState;
}
}
package FiveChess;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;
import javax.swing.JOptionPane;
public class ServerAgentThread extends Thread{
ChessServer father;
ServerThread st;//声明服务器线程的引用
Socket sc;//声明Socket引用
boolean flag=true;//控制该线程的标志位
DataInputStream din;//声明数据输入流
DataOutputStream dout;//声明数据输出流
public ServerAgentThread(ChessServer father,Socket sc,ServerThread st){//构造器 this.father=father;
this.sc=sc;
this.st=st;
try{//创建输入输出流
din=new DataInputStream(sc.getInputStream());
dout=new DataOutputStream(sc.getOutputStream());
}
catch(Exception e){e.printStackTrace();}
}
public void run(){
String msg1="";
while(flag){
try{
String msg=din.readUTF().trim();//接收客户端信息 if(msg1.equals(msg)) msg=""; if(msg.startsWith("<#NICK_NAME#>")){//如果传来的是名字 JOptionPane.showMessageDialog(father,msg.substring(13)+"加入 "提示",JOptionPane.INFORMATION_MESSAGE);//弹出加入游戏的 游戏", 对话框 话框 father.jbStart.setEnabled(true);//将"开始"按钮设为可用 } else if(msg.startsWith("<#ClientDown#>")){//收到服务器离开的信息 father.jpz.setGameState(false);//设置jpz状态为,停止游戏 this.flag=false;//设置该线程标志位,停止该线程 this.sc.close();//关闭Socket st.setHasPerson(false);//设置服务器线程标志位 father.sat=null;//将主窗体的代理线程设为空 JOptionPane.showMessageDialog(father,"客户离开了!!!","提示", JOptionPane.INFORMATION_MESSAGE);//弹出提示对 father.setState(true);//设置客户端主窗体的状态
}else if(msg.startsWith("<#ClientWin#>")){
father.jpz.setGameState(false);
JOptionPane.showMessageDialog(father,"白棋胜!!!","提示", JOptionPane.INFORMATION_MESSAGE);//弹出提示对话框
father.jpz.setReady(false);
}
else if(msg.startsWith("<#ClientChess#>")){//收到服务器下子的消息 String info=msg.substring(15);//获得有用信息
String[] detail=info.split("/");//分解信息
int chess_id=new Integer(detail[0]);
int chess_x=new Integer(detail[1]);
int chess_y=new Integer(detail[2]);
int state=new Integer(detail[3]);
father.jpz.mouse.addChess(chess_id, chess_x, chess_y, state); father.jpz.setChess_id(chess_id);
father.jpz.repaint();
msg1=msg;
}
else if(msg.startsWith("<#Ready#>")){
father.jpz.setReady(true);
msg1=msg;
}
else if(msg.startsWith("<#CancelReady#>")){
father.jpz.setReady(false);
msg1=msg;
}
else if(msg.startsWith("<#ClientMessage#>")){
String info=msg.substring(17)+"\n";
father.jaChat.insert(info, father.textIndex);
father.textIndex+=info.length();
msg1=msg;
}
}catch(Exception e){e.printStackTrace();}
}
}
public void setFlag(boolean flag){this.flag=flag;}
}
package FiveChess;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerThread extends Thread{
ChessServer father;//声明服务器主类的引用
ServerSocket ss;//声明ServerSocket引用
boolean flag=true;//控制线程的标志位
boolean hasPerson=false;//是否已经有客户端连接上
public ServerThread(ChessServer father,ServerSocket ss){//构造器 this.father=father;
this.ss=ss;
}
public void run(){//重写的run方法
while(flag){
} if(hasPerson==false){//如果还没有客户端连接 try{ Socket sc=ss.accept();//等待客户端连接 ServerAgentThread sat=new ServerAgentThread(father,sc,this); sat.start();//当有连接时,为其分配一个服务器代理线程并启动 father.sat=sat; this.hasPerson=true; } catch(Exception e){e.printStackTrace();} } else { try { Thread.sleep(1000); } catch(Exception e) { e.printStackTrace(); } } } } public void setFlag(boolean flag){//设置标志位的方法 this.flag=flag; } public void setHasPerson(boolean hasPerson){//设置线程状态的方法 this.hasPerson=hasPerson; }
package FiveChess;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter; import java.io.IOException;
//import java.util.ArrayList;
//import java.util.HashMap;
import java.util.Iterator;
//import java.util.Map;
import java.util.Set;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class ServerWar extends JPanel {
ChessBoard chessBoard =new ChessBoard(); Chess chess[]=new Chess[500];
boolean gameState=false;
boolean oneGameState=false;
boolean ready=false;
int serverChessType=-1;
int Chess_id=0;
// SPaintThread spt;
ChessServer father;
mouseListener mouse=new mouseListener(); public ServerWar(ChessServer father){ this.father=father;
// spt=new SPaintThread(father);//创建
绘制线程
// spt.start();//启动该绘制线程 // setBackground(Color.gray);
addMouseListener(mouse);
chess[0]=new Chess(0,0,0,0); }
public void paintComponent(Graphics g){ super.paintComponent(g);
chessBoard.draw(g);
int i=0;
while(i<=Chess_id){
draw(g, chess
[i]);
i++;
}
// }
}
public void draw(Graphics g,Chess ch){
ch.drawChess(g);
}
class mouseListener extends MouseAdapter { public void mouseReleased
(MouseEvent e){
if
(gameState==true&&chess[Chess_id].state!
=serverChessType){
int x=e.getX();
int y=e.getY();
if(x%30<=15)
x=x/30;
else if(x
%30>15) x=x/30+1;
if(y%30<=15)
y=y/30;
else if(y
%30>15) y=y/30+1;
if
(x>0&&y>0&&x<16&&y<16&&chessBoard.getState(x, y)
==0){
Chess_id++;
addChess(Chess_id,x,y,serverChessType);
chessBoard.setState(x, y, serverChessType);
//验
证是否构成五子
if
(isFive(x,y)){
this.sendMsg("<#ServerWin#>");
setGameState(false);
JOptionPane.showMessageDialog(father,"黑棋胜!!!","
提示",
JOptionPane.INFORMATION_MESSAGE);//弹出提
示对话框
setReady(false);
}
repaint();
}
}
else if
(oneGameState==true){
//单
人游戏过程
}
else if
(gameState==false&&oneGameState==false)
JOptionPane.showMessageDialog(father,"请先开始游戏!
",
"提
示",JOptionPane.INFORMATION_MESSAGE);
}
public boolean isFive(int chess_x,int
chess_y){
int level=1;
int x=chess_x;
int y=chess_y;
while
(x>1&&chessBoard.board[x-1][y]==serverChessType){ level++;
if(level==5){
return true;
}
x--;
}
x=chess_x;
y=chess_y;
while
(x<15&&chessBoard.board[x+1][y]==serverChessType){ level++;
if(level==5){
return true;
}
x++;
}
int apeak=1;
x=chess_x;
y=chess_y;
while
(y>1&&chessBoard.board[x][y-1]==serverChessType){ apeak++;
if(apeak==5){
return true;
}
y--;
}
x=chess_x;
y=chess_y;
while
(y<15&&chessBoard.board[x][y+1]==serverChessType){ apeak++;
if(apeak==5){
return true;
}
y++;
}
int bias1=1;
x=chess_x;
y=chess_y;
while
(x>1&&y>1&&chessBoard.board[x-1][y-1]
==serverChessType){
bias1++;
if(bias1==5){
return true;
}
x--;y--;
}
x=chess_x;
y=chess_y;
while
(x<15&&y<15&&chessBoard.board[x+1][y+1]
==serverChessType){
bias1++;
if(bias1==5){
return true;
}
x++;y++;
}
int bias2=1;
x=chess_x;
y=chess_y;
while
(x<15&&y>1&&chessBoard.board[x+1][y-1]
==serverChessType){
bias2++;
if(bias2==5){
return true;
}
x++;y--;
}
x=chess_x;
y=chess_y;
while
(x>1&&y<15&&chessBoard.board[x-1][y+1]
==serverChessType){
bias2++;
if(bias2==5){
return true;
}
x--;y++;
}
return false;
}
public void addChess(int id,int x,int
y,int state){
Chess serverChess=new
Chess(id,x,y,state);
// m_chess.put(id,
serverChess);
chess[id]=serverChess;
this.sendMsg
("<#ServerChess#>"+serverChess.getId
()+"/"+serverChess.getChess_x
()+"/"+serverChess.getChess_y()+
"/"+serverChess.getState());
}
public void sendMsg(String msg){//用
于向服务器发送消息的方法
try{
father.sat.dout.writeUTF(msg);//发送消息 }
catch(IOException e)
{e.printStackTrace();}
}
}
public void setGameState(boolean gameState){ this.gameState=gameState;
}
public void setChess_id(int chess_id) { Chess_id = chess_id;
}
public int getServerChessType() {
return serverChessType;
}
public void setServerChessType(int
serverChessType) {
this.serverChessType =
serverChessType;
}
public void setOneGameState(boolean
oneGameState) {
this.oneGameState =
oneGameState;
}
public void setReady(boolean ready) { this.ready = ready;
}
}
package FiveChess;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.TextArea;
import java.awt.Toolkit;
import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.IOException;
import java.net.Socket;
import java.sql.Time;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.JTextField;
public class ChessClient extends JFrame implements ActionListener { public static final int frame_width=35;//窗体的宽度 public static final int frame_height=27;//窗体的高度
public static final int frame_opration=10;//操作区域的宽度 public static final int block_width=20;//单位宽度
public static final int block_height=20;//单位高度
ClientWar jpz=new ClientWar(this);//创建客户端主面板
JMenuBar menubar=new JMenuBar();//创建菜单条 JMenu fileMenu=new JMenu("文件"); JMenuItem one = new JMenuItem("单人游戏"); JMenuItem two =new JMenuItem("双人游戏"); JMenuItem exit=new JMenuItem("退出"); JPanel jpy=new JPanel();//创建操作区的面板 JLabel jlHost=new JLabel("主机名");//提示输入主机ip的标签 JTextField jtfHost=new JTextField("127.0.0.1");//输入主机ip的文本框,默认是127.0.0.1 JLabel jlPort=new JLabel("端口号");//提示输入端口号的标签 JTextField jtfPort=new JTextField("9999");//输入端口号的文本框,默认是9999 JLabel jlNickName=new JLabel("昵 称");//提示输入昵称的标签 JTextField jtfNickName=new JTextField("Player");//输入昵称的文本框,默认是player JButton jbConnect=new JButton("连接");//创建"连接"按钮 JButton jbDisConnect=new JButton("断开");//创建"断开"按钮 JButton jbStart=new JButton("开始"); JButton jbReady=new JButton("准备"); JButton jbSend=new JButton("发送"); TextArea jaChat=new TextArea("",5000,1,TextArea.SCROLLBARS_VERTICAL_ONLY); int textIndex=0; JTextField jtfMessage=new JTextField("你好"); JSplitPane jsp=new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,jpz,jpy);//创建JSplitPane Socket sc;//声明Socket引用 ClientAgentThread cat;//声明客户端代理线程的引用 public ChessClient(){//构造器
} this.addComponent();//初始化窗体,将控件添加到窗体中 this.addListener();//为相应控件注册监听器 this.initialFrame();//初始化窗体 jpz.setFocusable(true); jpz.requestFocus(true);//使左边面板获得焦点 public void addComponent(){//添加控件 的方法 jpy.setLayout(null);//设为空布局 jlHost.setBounds(10,30,40,25); jpy.add(jlHost);//添加"主机名"标签 jtfHost.setBounds(55,30,100,25); jpy.add(jtfHost);//添加输入主机名的标签 jlPort.setBounds(10,60,40,25); jpy.add(jlPort);//添加"端口号"标签 jtfPort.setBounds(55,60,100,25); jpy.add(jtfPort);//添加输入端口号的标签 jlNickName.setBounds(10,90,40,25); jpy.add(jlNickName);//添加"昵称"标签 jtfNickName.setBounds(55,90,100,25); jpy.add(jtfNickName);//添加输入昵称的文本框 jbConnect.setBounds(20,120,60,20); jpy.add(jbConnect);//添加"连接"按钮 jbDisConnect.setBounds(100,120,60,20); jpy.add(jbDisConnect);//添加"断开"按钮 jbReady.setBounds(20, 150, 60, 20); jbReady.setBackground(Color.white); jpy.add(jbReady); jbStart.setBounds(40, 190, 80, 20); jpy.add(jbStart); jaChat.setBounds(10, 230, 160, 205); jaChat.setEditable(false); jpy.add(jaChat); jtfMessage.setBounds(10, 440, 100, 25); jpy.add(jtfMessage); jbSend.setBounds(120, 440, 60, 20); jpy.add(jbSend); jsp.setDividerLocation((frame_width-frame_opration)*block_width); jsp.setDividerSize(4);//设置JSplitPane分割线的位置及宽度 this.add(jsp);//添加jsp fileMenu.add(one); fileMenu.add(two); fileMenu.addSeparator(); fileMenu.add(exit);
} menubar.add(fileMenu); this.add(menubar,BorderLayout.NORTH); public void addListener(){//为控件注册时间监听器 jbConnect.addActionListener(this); jbDisConnect.addActionListener(this); one.addActionListener(this); two.addActionListener(this); exit.addActionListener(this); jbStart.addActionListener(this); jbReady.addActionListener(this); jbSend.addActionListener(this); } public void actionPerformed(ActionEvent e){
if(e.getSource()==this.jbConnect){//当用户单击"连接"时
int port=0;
try{//获得用户输入的端口号
port=Integer.parseInt(this.jtfPort.getText().trim());
}
catch(Exception ee){//如果不是数字则给出提示
JOptionPane.showMessageDialog(this,"端口号只能是整数","错误", JOptionPane.ERROR_MESSAGE); return;
}
if(port>65535||port<0){//判断端口号是否在有效范围内
JOptionPane.showMessageDialog(this,"端口号只能是0-65535的整数","错
} JOptionPane.ERROR_MESSAGE); return; 误", String name=this.jtfNickName.getText().trim();//获得昵称 if(name.length()==0){//昵称为空则给出提示信息 JOptionPane.showMessageDialog(this,"玩家姓名不能为空","错误", JOptionPane.ERROR_MESSAGE); return; } try{ this.setState(false); sc=new Socket(this.jtfHost.getText().trim(),port);//创建Socket进行连接 cat=new ClientAgentThread(this,sc); //连接成功,创建代理线程 cat.start();//启动代理线程 JOptionPane.showMessageDialog(this,"已连接到服务器","提示",
} JOptionPane.INFORMATION_MESSAGE);//给出连接成功的提示 } catch(Exception ee){ JOptionPane.showMessageDialog(this,"连接服务器失败","错误", JOptionPane.ERROR_MESSAGE);//连接失败,给出提示 this.setState(true); return; } else if(e.getSource()==this.jbDisConnect){//当用户单击"断开"按钮时 try{ cat.dout.writeUTF("<#ClientDown#>");//向服务器端发送离开的消息 cat.setFlag(false);//结束代理线程 sc.close();//关闭连接 } catch(IOException ea){ea.printStackTrace();} jpz.setGameState(false); this.setState(true); } else if(e.getSource()==this.one){
//与计算机游戏
setOneGameState(true);
}
else if(e.getSource()==this.two){
jpz.setOneGameState(false);
jbStart.setEnabled(false);
setState(true);
}
else if(e.getSource()==this.exit){
int result=JOptionPane.showConfirmDialog(this,"是否要退出?", "提示",JOptionPane.YES_NO_OPTION);
if(result==0){
System.exit(0);
}
}
else if(e.getSource()==this.jbStart){
int result=JOptionPane.showConfirmDialog(this,"是否开始新单机游戏?", "提示",JOptionPane.YES_NO_OPTION);
if(result==0){
setOneGameState(true);
jpz.setOneGameState(true);
jpz.setChess_id(0);
jpz.chess=new Chess[255];
jpz.chess[0]=new Chess(0,0,0,0);
} } else if(e.getSource()==this.jbReady){ if(jbReady.getBackground()==Color.gray&&jpz.gameState==false) { try { cat.dout.writeUTF("<#CancelReady#>"); } catch (IOException e1) { e1.printStackTrace(); } jbReady.setBackground(Color.white); }else if(jbReady.getBackground()==Color.white){ try { cat.dout.writeUTF("<#Ready#>"); } catch (IOException e1) { e1.printStackTrace(); } jbReady.setBackground(Color.gray); jpz.setChess_id(0); jpz.chess=new Chess[255]; jpz.chess[0]=new Chess(0,0,0,0); } } else if(e.getSource()==this.jbSend){ if(jtfMessage.getText().trim().equals("")){ jaChat.setForeground(Color.red);
jaChat.insert("不能发送空消息。\n",textIndex);
jaChat.setForeground(Color.black);
}else{
Time time=new Time(System.currentTimeMillis());
String message=jtfNickName.getText()+" "+time.getHours()+":"+time.getMinutes()+":"+time.getSeconds()+"\n"+jtfMessage.getText()+"\n";
try {
cat.dout.writeUTF("<#ClientMessage#>"+message);
} catch (IOException e1) {
e1.printStackTrace();
}
jtfMessage.setText("");
jaChat.insert(message, textIndex);
textIndex+=message.length();
}
}
jpz.requestFocus(true);
//
// } public void initialFrame(){//初始化窗体的方法 this.setOneGameState(true); this.setState(true); Image image=new ImageIcon("ico.gif").getImage();
this.setIconImage(image); //设置图标
this.setTitle("FiveChess--Client");//设置标题
this.setResizable(false);
Dimension screenSize = //获得屏幕尺寸
Toolkit.getDefaultToolkit().getScreenSize();
int centerX=screenSize.width/2;//计算屏幕中心坐标
int centerY=screenSize.height/2;
int width=frame_width*block_width;//计算窗体的高和宽
int height=frame_height*block_height; //
this.setBounds(centerX-width/2,centerY-height/2-30,width,height);//使窗体居中显示 this.addWindowListener(
new WindowAdapter(){
public void windowClosing(WindowEvent e){
if(cat==null){//如果代理线程是空则直接退出
System.exit(0);
return;
}
try{
cat.dout.writeUTF("<#ClientDown#>");//代理线程不是空,向服务器端发送离开的消息
cat.setFlag(false);
sc.close();//关闭socket
}
catch(IOException ea){ea.printStackTrace();}
System.exit(0);
}
}
);
this.setVisible(true);
}
public void setOneGameState(boolean state){
jtfHost.setEnabled(!state);
jbConnect.setEnabled(!state);
jbDisConnect.setEnabled(!state);
jtfPort.setEnabled(!state);
jtfNickName.setEnabled(!state);
jbReady.setEnabled(!state);
jbStart.setEnabled(state);
jpz.setGameState(!state);
} } jpz.setOneGameState(!state); jaChat.setEnabled(!state); jbSend.setEnabled(!state); jtfMessage.setEnabled(!state); public void setState(boolean state){//设置窗体状态的方法 jtfHost.setEnabled(state); jtfPort.setEnabled(state); jtfNickName.setEnabled(state); jbConnect.setEnabled(state); jbDisConnect.setEnabled(!state); jbReady.setEnabled(!state); jaChat.setEnabled(!state); jbSend.setEnabled(!state); jtfMessage.setEnabled(!state); } public static void main(String[] args) { new ChessClient(); } public int getTextIndex() { return textIndex; } public void setTextIndex(int textIndex) { this.textIndex = textIndex; }