package com.lovo;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Stroke;
/**
* 棋盘类
*/
public class Board {
private int[][] b = new int[15][15];
/**
* 绘制棋盘
* @param g 画笔
*/
public void draw(Graphics g) {
g.setColor(Color.BLACK);
Graphics2D g2d = (Graphics2D) g; // 画笔加粗需要引用的处理;
Stroke oldStroke = g2d.getStroke(); // 记录画笔原来的粗细(保存现场)
g2d.setStroke(new BasicStroke(5)); // 修改画笔的粗细
g.drawRect(50, 50, 700, 700); // 绘制边框
g2d.setStroke(oldStroke); // 将画笔还远为原来的粗细(恢复现场)
for (int i = 0; i < 13; i++) {
g.drawLine(50, 100 + 50 * i, 750, 100 + 50 * i);
g.drawLine(100 + 50 * i, 50, 100 + 50 * i, 750);
}
// 绘制天元
g.fillOval(390, 390, 20, 20);
// 绘制四颗星
g.fillOval(195, 195, 10, 10);
g.fillOval(595, 595, 10, 10);
g.fillOval(195, 595, 10, 10);
g.fillOval(595, 195, 10, 10);
for(int i =0; i < b.length; i++){ // 行控制纵坐标
for(int j =0; j < b[i].length; j++){ // 列控制横坐标
if(b[i][j] != 0) {
g.setColor(b[i][j] == 1? Color.BLACK : Color.WHITE); // 设置画笔颜色
g.fillOval(25 + 50 * j, 25 + 50 * i, 50, 50); // 绘制棋子
}
}
}
}
/**
* 走棋(落子)
* @param row 落子的行
* @param col 落子的列
* @param isBlack 是否为黑棋
* @return 落子成功返回true否则返回false
*/
public boolean move(int row, int col, boolean isBlack) {
if(b[row][col] == 0) {
b[row][col] = isBlack ? 1 : 2;
return true;
}
return false;
}
/**
* 判断胜负
* @return 有任意一方获胜返回true, 否则返回false
*/
public boolean judge(int row, int col, boolean isBlack) {
int currentColor = isBlack ? 1 : 2;
return countV(row, col, currentColor) >= 5 || countH(row, col, currentColor) >= 5 ||
countX1(row, col, currentColor) >= 5 || countX2(row, col, currentColor) >= 5;
}
// 计算垂直方向连续同色棋子的数量
private int countV(int row, int col, int currentColor) {
int counter = 1;
int tempRow = row;
while(tempRow - 1 >= 0 && b[tempRow - 1][col] == currentColor) {
tempRow -= 1;
counter++;
}
tempRow = row;
while(tempRow + 1 < b.length && b[tempRow + 1][col] == currentColor) {
tempRow += 1;
counter++;
}
return counter;
}
// 计算水平方向连续同色棋子的数量
private int countH(int row, int col, int currentColor) {
int counter = 1;
int tempCol = col;
while(tempCol - 1 >= 0 && b[row][tempCol - 1] == currentColor) {
tempCol -= 1;
counter++;
}
tempCol = col;
while(tempCol + 1 < b.length && b[row][tempCol + 1] == currentColor) {
tempCol += 1;
counter++;
}
return counter;
}
// 计算反对角线方向连续同色棋子的数量
private int countX1(int row, int col, int currentColor) {
int counter = 1;
int tempRow = row;
int tempCol = col;
while(tempRow - 1 >= 0 && tempCol - 1 >= 0 && b[tempRow - 1][tempCol - 1] == currentColor) {
tempRow -= 1;
tempCol -= 1;
counter++;
}
tempRow = row;
tempCol = col;
while(tempRow + 1 < b.length && tempCol + 1 < b.length && b[tempRow + 1][tempCol + 1] == currentColor) {
tempRow += 1;
tempCol += 1;
counter++;
}
return counter;
}
// 计算正对角线方向连续同色棋子的数量
private int countX2(int row, int col, int currentColor) {
int counter = 1;
int tempRow = row;
int tempCol = col;
while(tempRow - 1 >= 0 && tempCol + 1 < b.length && b[tempRow - 1][tempCol + 1] == currentColor) {
tempRow -= 1;
tempCol += 1;
counter++;
}
tempRow = row;
tempCol = col;
while(tempRow + 1 < b.length && tempCol - 1 >= 0 && b[tempRow + 1][tempCol - 1] == currentColor) {
tempRow += 1;
tempCol -= 1;
counter++;
}
return counter;
}
public void reset() {
for(int i = 0; i < b.length; i++) {
for(int j = 0; j < b[i].length; j++) {
b[i][j] = 0;
}
}
}
// public void makeAMove() {
// int row = (int) (Math.random() * 15);
// int col = (int) (Math.random() * 15);
// if (b[row][col] == 0) {
// b[row][col] = blackTurn ? 1 : 2;
// blackTurn = !blackTurn; // 交换走棋方
// }
// }
}
package com.lovo;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
@SuppressWarnings("serial")
public class GameFrame extends JFrame {
private GameServer server = null;
private GameClient client = null;
private Board board = new Board(); // 创建棋盘类的对象;
private Image offImage = new BufferedImage(800, 800,
BufferedImage.TYPE_INT_RGB);
private boolean isMyTurn = true; // 是否轮到黑方走棋(true-黑方,false-白方)
private boolean isGameOver = false;
private boolean isBlack = true;
private boolean isGameServerOn = false;
public GameFrame() {
this.setTitle("五子棋");
this.setSize(800, 800);
this.setResizable(false);
this.setLocationRelativeTo(null);
this.getContentPane().setBackground(new Color(0xCF9D0A));
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(java.awt.event.WindowEvent e) {
if(server != null) {
server.close();
}
if(client != null) {
client.close();
}
System.exit(0);
}
});
this.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
if(isMyTurn && !isGameOver && isGameServerOn) {
int x = e.getX();
int y = e.getY();
if(x >= 50 && x <= 750 && y >= 50 && y <= 750) {
int row = Math.round((y - 50) / 50.0F);
int col = Math.round((x - 50) / 50.0F);
if(board.move(row, col, isBlack)) {
repaint();
if(server != null) {
try {
server.sendMove(row, col, isBlack);
new Thread(new Runnable() {
@Override
public void run() {
try {
MoveInfo mi = server.receiveMove();
board.move(mi.getRow(), mi.getCol(), mi.isBlack());
if(board.judge(mi.getRow(), mi.getCol(), mi.isBlack())) {
isGameOver = true;
isMyTurn = false;
}
else {
isMyTurn = true;
}
repaint();
}
catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
catch (IOException ex) {
ex.printStackTrace();
}
}
else if(client != null) {
try {
client.sendMove(row, col, isBlack);
new Thread(new Runnable() {
@Override
public void run() {
try {
MoveInfo mi = client.receiveMove();
board.move(mi.getRow(), mi.getCol(), mi.isBlack());
if(board.judge(mi.getRow(), mi.getCol(), mi.isBlack())) {
isGameOver = true;
isMyTurn = true;
}
else {
isMyTurn = true;
}
repaint();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
catch (IOException ex) {
ex.printStackTrace();
}
}
if(board.judge(row, col, isMyTurn)) {
isGameOver = true;
}
else {
isMyTurn = !isMyTurn;
}
}
}
}
}
});
this.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if(isGameOver && e.getKeyCode() == KeyEvent.VK_F2) {
resetGame();
repaint();
}
else if(!isGameServerOn && e.getKeyCode() == KeyEvent.VK_F3) {
server = new GameServer();
new Thread(new Runnable() {
@Override
public void run() {
try {
server.start();
isGameServerOn = true; // 主机启动成功
isMyTurn = true; // 轮到自己走棋
isBlack = true;
}
catch (Exception ex) {
JOptionPane.showMessageDialog(null, "建立主机失败!!!", "错误", JOptionPane.ERROR_MESSAGE);
}
}
}).start();
}
else if(!isGameServerOn && e.getKeyCode() == KeyEvent.VK_F4) {
String ip = JOptionPane.showInputDialog("请输入要连接的主机(IP地址或机器名): ");
client = new GameClient();
try {
client.start(ip);
isGameServerOn = true;
isMyTurn = false;
isBlack = false;
new Thread(
new Runnable() {
@Override
public void run() {
try {
MoveInfo mi = client.receiveMove();
board.move(mi.getRow(), mi.getCol(), mi.isBlack());
isMyTurn = true;
repaint();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
).start();
}
catch (Exception ex) {
JOptionPane.showMessageDialog(null, "连接主机失败!!!", "错误", JOptionPane.ERROR_MESSAGE);
}
}
}
// 重置游戏
private void resetGame() {
board.reset();
isMyTurn = true;
isGameOver = false;
}
});
}
@Override
public void paint(Graphics g) { // 重写此方法的目的是在窗口上绘制自己想要的东西
Graphics newG = offImage.getGraphics();
super.paint(newG); // 消除窗口残影
board.draw(newG); // 棋盘对象调用draw方法
if(isGameOver) {
newG.setColor(isMyTurn ? Color.BLACK : Color.WHITE);
newG.setFont(new Font("微软雅黑", Font.PLAIN, 72));
newG.drawString(isMyTurn? "黑棋胜" : "白棋胜", 293, 150);
}
g.drawImage(offImage, 0, 0, 800, 800, null); // 将内存中的图直接绘制到窗口上
}
}
package com.lovo;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class GameServer {
private ServerSocket server;
private Socket client;
private InputStream in;
private OutputStream out;
private boolean connected;
public void start() throws Exception {
server = new ServerSocket(5566);
client = server.accept();
in = client.getInputStream();
out = client.getOutputStream();
connected = true;
}
public void sendMove(int row, int col, boolean isBlack) throws IOException {
DataOutputStream dout = new DataOutputStream(out);
dout.writeInt(row);
dout.writeInt(col);
dout.writeBoolean(isBlack);
}
public MoveInfo receiveMove() throws IOException {
MoveInfo mi = new MoveInfo();
DataInputStream din = new DataInputStream(in);
mi.setRow(din.readInt());
mi.setCol(din.readInt());
mi.setBlack(din.readBoolean());
return mi;
}
public void close() {
if(client != null) {
try {
client.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
if(server != null) {
try {
server.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
public boolean isConnected() {
return connected;
}
}
package com.lovo;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class GameClient {
private Socket client;
private InputStream in;
private OutputStream out;
public void start(String ip) throws Exception {
client = new Socket(ip, 5566);
in = client.getInputStream();
out = client.getOutputStream();
}
public void sendMove(int row, int col, boolean isBlack) throws IOException {
DataOutputStream dout = new DataOutputStream(out);
dout.writeInt(row);
dout.writeInt(col);
dout.writeBoolean(isBlack);
}
public MoveInfo receiveMove() throws IOException {
MoveInfo mi = new MoveInfo();
DataInputStream din = new DataInputStream(in);
mi.setRow(din.readInt());
mi.setCol(din.readInt());
mi.setBlack(din.readBoolean());
return mi;
}
public void close() {
if(client != null) {
try {
client.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
}
package com.lovo;
public class MoveInfo {
private int row;
private int col;
private boolean isBlack;
public int getRow() {
return row;
}
public void setRow(int row) {
this.row = row;
}
public int getCol() {
return col;
}
public void setCol(int col) {
this.col = col;
}
public boolean isBlack() {
return isBlack;
}
public void setBlack(boolean isBlack) {
this.isBlack = isBlack;
}
}
package com.lovo;
public class GameRunner {
public static void main(String[] args) {
new GameFrame().setVisible(true);
}
}