📄 omokclient.java
字号:
/*
作者:黄渊 220300124 陈烨 220300123 参考资料:JAVA编程基础、应用实例
*/
import java.awt.*;
import java.net.*;
import java.io.*;
import java.util.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;
class OmokBoard extends Canvas{ //五子棋盘类
public static final int BLACK=1,WHITE=-1; //黑白子常数
private int[][] map; //map数组
private int size; //棋盘大小
private int cell; //棋盘单元格大小
private String info="游戏终止"; //游戏状态字符串
private int color=BLACK;
//若为true,则表示用户可以放置棋子
//若为false,则表示用户不可放置棋子
private boolean enable=false;
private boolean running=false; //显示游戏是否运行的变量
private PrintWriter writer; //向对方棋手传递信息的流
private Graphics gboard,gbuff;
private Image buff;
OmokBoard(int s,int c){ //五子棋盘的构造函数(s=15,c=30)
this.size=s;
this.cell=c;
map=new int[size+2][]; //确定map函数的大小
for(int i=0;i<map.length;i++)
map[i]=new int[size+2];
setBackground(new Color(150,200,254)); //设定五子棋盘的背景色
setSize(size*(cell+1)+size,size*(cell+1)+size); //计算棋盘的大小
//棋盘鼠标事件
addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent me){ //鼠标按下事件
if(!enable)return;
//将鼠标坐标转换为map坐标
int x=(int)Math.round(me.getX()/(double)cell);
int y=(int)Math.round(me.getY()/(double)cell);
//如果不是在下棋区内的坐标,则退出事件
if(x==0||y==0||x==size+1||y==size+1)return;
//如果不是在下棋区内的坐标,但该单位已经有子了,照样退出按下鼠标事件
if(map[x][y]==BLACK||map[x][y]==WHITE)return;
//向对方棋手发送棋子坐标的信息
writer.println("[STONE]"+x+" "+y);
//给坐标发颜色,显现出棋子来
map[x][y]=color;
//检查获胜与否
if(check(new Point(x,y),color)){
info="获胜";
writer.println("[WIN]");
}
else info="等待对方落子";
repaint(); //绘制棋盘
//用户不可下子
//若对手下完子,则将enable的值改成true,此时用户方可落子
enable=false;
}
});
}
public boolean isRunning(){ //获取游戏的运行状态
return running;
}
public void startGame(String col){ //开始游戏
running=true;
if(col.equals("BLACK")){ //若黑棋被选中
enable=true;
color=BLACK;
info=" 开始游戏。。。请落子";
}
else{ //选种百棋
enable=false;
color=WHITE;
info="开始游戏。。。请等待对方落子";
}
}
public void stopGame(){ //停止游戏
reset(); //初始化棋盘
writer.println("[STOPGAME]"); //向对手发信息
enable=false;
running=false;
}
public void putOpponent(int x,int y){
map[x][y]=-color;
info="对手已经落子,请落子";
repaint();
}
public void setEnable(boolean enable){
this.enable=enable;
}
public void setWriter(PrintWriter writer){
this.writer=writer;
}
public void update(Graphics g){ //调用repaint()时自动调用
paint(g); //调用paint()方法
}
public void paint(Graphics g){ //绘制画面
if(gbuff==null){
buff=createImage(getWidth(),getHeight());
gbuff=buff.getGraphics();
}
drawBoard(g); //绘制棋盘
}
public void reset(){ //初始化棋盘
for(int i=0;i<map.length;i++)
for(int j=0;j<map[i].length;j++)
map[i][j]=0;
info="游戏终止";
repaint();
}
private void drawLine(){
String line = "a b c d e f g h i j k l m n o";
char [] rowNum1 = {'1','2','3','4','5','6','7','8','9'};
char [] rowNum2={'1','0','1','1','1','2','1','3','1','4','1','5'}; //在棋盘上画线
gbuff.setColor(Color.black);
gbuff.drawString(line,25,15);
for(int i=0;i<9;i++){
gbuff.drawChars(rowNum1,i,1,10,35+i*30);
}
for(int i=9,j=0;i<15;i++,j+=2){
gbuff.drawChars(rowNum2,j,2,10,35+i*30);
}
for(int i=1;i<=size;i++){
gbuff.drawLine(cell,i*cell,cell*size,i*cell);
gbuff.drawLine(i*cell,cell,i*cell,cell*size);
}
gbuff.drawLine(25,25,25,455);
gbuff.drawLine(25,25,455,25);
gbuff.drawLine(455,25,455,455);
gbuff.drawLine(25,455,455,455);
}
private void drawBlack(int x,int y){ //在(x,y)上绘制黑棋
Graphics2D gbuff=(Graphics2D)this.gbuff;
gbuff.setColor(Color.black);
gbuff.fillOval(x*cell-cell/2,y*cell-cell/2,cell,cell);
}
private void drawWhite(int x,int y){ //在(x,y)上绘制白棋
gbuff.setColor(Color.white);
gbuff.fillOval(x*cell-cell/2,y*cell-cell/2,cell,cell);
}
private void drawStones(){ //绘制map中的所有棋子
for(int x=1;x<=size;x++)
for(int y=1;y<=size;y++){
if(map[x][y]==BLACK)
drawBlack(x,y);
else if(map[x][y]==WHITE)
drawWhite(x,y);
}
}
synchronized private void drawBoard(Graphics g){ //绘制棋盘
gbuff.clearRect(0,0,getWidth(),getHeight());
drawLine();
drawStones();
gbuff.setColor(Color.red);
gbuff.drawString(info,30,470);
g.drawImage(buff,0,0,this);
}
private boolean check(Point p,int col){ //获胜判定
if(count(p,1,0,col)+count(p,-1,0,col)==4)
return true;
if(count(p,0,1,col)+count(p,0,-1,col)==4)
return true;
if(count(p,-1,-1,col)+count(p,1,1,col)==4)
return true;
if(count(p,1,-1,col)+count(p,-1,1,col)==4)
return true;
return false;
}
private int count(Point p,int dx,int dy,int col){
int i=0;
for(;map[p.x+(i+1)*dx][p.y+(i+1)*dy]==col;i++);
return i;
}
}
public class OmokClient extends Frame implements Runnable,ActionListener{
private TextArea msgView=new TextArea("",1,1,1); //显示消息的多行文本框
private TextField sendBox=new TextField(""); //记录待发消息的对话框
private TextField nameBox=new TextField(); //用户名对话框
private TextField roomBox=new TextField(""); //房间号对话框
private Label pInfo=new Label("待机室:名");
private java.awt.List pList=new java.awt.List(); //显示用户名单列表
//private Button computerButton=new Button("人机对战");
private Button startButton=new Button("准备");
private Button stopButton=new Button("弃权");
private Button enterButton=new Button("入场");
private Button exitButton=new Button("去待机室");
//
private Label infoView=new Label("< JAVA 五子棋 >",1);
private OmokBoard board=new OmokBoard(15,30); //棋盘对象
private BufferedReader reader; //输入流
private PrintWriter writer; //输出流
private Socket socket; //套接字
private int roomNumber=-1; //房间号
private String userName=null; //用户名
public OmokClient(String title){ //构造函数
super(title);
setLayout(null);
this.setResizable(false); //不使用任何布局
//创建并排列各种组件
msgView.setEditable(false);
infoView.setBounds(10,30,480,30);
infoView.setBackground(new Color(150,200,254));
board.setLocation(10,70);
add(infoView);
add(board);
Panel p=new Panel();
p.setBackground(new Color(150,200,254));
p.setLayout(new GridLayout(3,3));
p.add(new Label("名字:",2));
p.add(nameBox);
p.add(new Label("房间号:",2));
p.add(roomBox);
p.add(enterButton);
p.add(exitButton);
enterButton.setEnabled(true);
p.setBounds(500,30,250,70);
Panel p2=new Panel();
p2.setBackground(new Color(150,200,254));
p2.setLayout(new BorderLayout());
Panel p2_1=new Panel();
//p2_1.add(computerButton);
p2_1.add(startButton);
p2_1.add(stopButton);
p2.add(pInfo,"North");
p2.add(pList,"Center");
p2.add(p2_1,"South");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -