⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chessgame.java

📁 Java五子棋 支持本地游戏
💻 JAVA
字号:
import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

import java.lang.*;
import java.io.*;
import java.net.*;


enum ChessMan
{
	Black, White, Empty
}

enum GameType
{
	LocalGame, ComputerGame, NetGame
}

enum GameStatus
{
	NotReady, IsReady, Running, Over
}



/**
 * @author JiangLei
 * 
 * this class maintains the main components of the game
 *
 */

class ChessGame
{
	private static final long serialVersionUID = 1L;
	
	//define the map size
	static public final int mapSize = 15;
	//two dimension array stores the board information
	public ChessMan[][] chessMap = new ChessMan[mapSize][mapSize];
	
	//player information
	Player playerA;
	Player playerB;
	Player notLocalPlayer;
	Player activePlayer = playerA;
	
	//the game panel
	ChessPad cpad = new ChessPad(this);
	
	//the player status panel
	PlayerStatusPanel playerPanelA;
	PlayerStatusPanel playerPanelB;
	
	//specify whether it's a local game, or a Human Vs. Computer or net game
	GameType gameType;
	
	//number of chess left in the board
	int chessLeft = mapSize * mapSize;
	
	//total time for the game
	int totalTime;
	
	//specify whether the game is ready or running or over
	GameStatus status = GameStatus.NotReady;
	
	//some additional elements for a net game
	Thread netChessThread; 
	Socket sock;
	Socket chatSock;
	
	//thread for a computer game
	Thread AIThread;
	
	
	/**
	 * 
	 * @param p1 specify the player with black chessman
	 * @param p2 specify the player with white chessman
	 * @param localPlayer specify the player who is in front of this computer
	 * @param totalTime the total time set up for the game
	 * @param gType specify which kind of game it is expected to be
	 */
	ChessGame(Player p1, Player p2, Player localPlayer, int totalTime, GameType gType)
	{
		playerA = p1;
		playerB = p2;
		playerPanelA = new PlayerStatusPanel(playerA, totalTime, this);
		playerPanelB = new PlayerStatusPanel(playerB, totalTime, this);
		
		playerA.playerPanel = playerPanelA;
		playerB.playerPanel = playerPanelB;
		
		gameType = gType;
		this.totalTime = totalTime;

		//empty the chess board
		for(int i = 0; i < mapSize; i++)
			for(int j = 0; j < mapSize; j++)
				chessMap[i][j] = ChessMan.Empty;
		
		cpad.listeningPlayer = localPlayer;
		notLocalPlayer = (localPlayer == playerA)?playerB:playerA;
	}
	
	/**
	 * startGame() start a new game
	 * 
	 */
	void startGame()
	{
		//empty the board
		for(int i = 0; i < mapSize; i++)
			for(int j = 0; j < mapSize; j++)
				chessMap[i][j] = ChessMan.Empty;
		//set up status
		status = GameStatus.Running;
		//set up player
		activePlayer = playerA;
		if(gameType == GameType.LocalGame)
			cpad.listeningPlayer = playerA;
		//reset the game time
		playerPanelA.timeLeftInSeconds = this.totalTime;
		playerPanelB.timeLeftInSeconds = this.totalTime;
		//refresh the frame
		MainFrame.mainFrame.repaint();
		
		//start count time 
		playerPanelA.chessTimer.start();
		
		//if not a local game, start the additional thread
		if(gameType == GameType.NetGame)
		{
			netChessThread = new NetChessThread(this);
			netChessThread.start();
		}
		else if(gameType == GameType.ComputerGame)
		{
			AIThread = new AIThread(this);
			AIThread.start();
		}
		
	}
	
	/**
	 * this method simulates the play game process, it put a chess of the active player on board, 
	 * and then judge if the player wins or there're no space left, else it'll automatically 
	 * switch to the other player 
	 * 
	 * @param x 	the x position of the chess 
	 * @param y		the y position of the chess
	 */
	void playChess(int x, int y)
	{
		this.chessMap[x][y] = this.activePlayer.chessMan;
		this.cpad.repaint();
    	
    	if(ChessGame.judge(x, y, this.chessMap))
    	{
    		gameOver();
    		//System.out.println(this.listeningPlayer.playerName + " wins!");
			String s = this.activePlayer.playerName + "获胜!";
			GameResultDialog d = new GameResultDialog(MainFrame.mainFrame, 100, 100, s); 
			d.setVisible(true);
    	}
    	else if(--chessLeft == 0)
    	{
    		gameOver();
    		//System.out.println("Nobody wins!");
			String s = "双方平局";
			GameResultDialog d = new GameResultDialog(MainFrame.mainFrame, 100, 100, s); 
			d.setVisible(true);
    	}
    	else
    	{
    		activePlayer.playerPanel.chessTimer.stop();
	    	activePlayer = (activePlayer == playerA)?playerB:playerA;
	    	activePlayer.playerPanel.chessTimer.start();
    	}
    	
    	return;
	}
	
	/**
	 * this method test if the latest chess will contribute to a FIVE
	 * 
	 * @param x		the x position of the chess
	 * @param y		the y position of the chess
	 * @return		whether there is a FIVE
	 */
	static boolean judge(int x, int y, ChessMan[][] chessMap)
	{
		int ax = x;
		int ay = y;
		int count = 0;
		
		//analysis the horizontal line
	    while(ax < mapSize && chessMap[ax][ay] == chessMap[x][y]){
	    	count++;
    		ax++;
	    }
	    ax=x;
	    count--;
	    
	    while(ax >= 0 && chessMap[ax][ay] == chessMap[x][y]){
	    	 count++;
    		 ax--;
	    }

	    if(count > 4){
	    	 return true;
    	}
	     
	    //analysis the vertical line
	    ax=x;
	    count=0;
	    while(ay < mapSize && chessMap[ax][ay] == chessMap[x][y]){
	    	count++;
    		ay++;
	    }
	    ay=y;
	    count--;
	    while(ay >= 0 && chessMap[ax][ay] == chessMap[x][y]){
	    	count++;
    		ay--;
	    }
	    if(count>4) {
	    	return true;
	    }
	    
	    //analysis the south east line
	    ax=x;
	    ay=y;
	    count=0;
	    while(ax >= 0 && ay >= 0 && chessMap[ax][ay] == chessMap[x][y]){
	    	count++;
    		ay--;
    		ax--;
	    }
	    ay=y;
	    ax=x;
	    count--;
	    while(ax < mapSize && ay < mapSize && chessMap[ax][ay] == chessMap[x][y]){
	    	count++;
    		ay++;
    		ax++;
	    }
	    if(count>4) {
	    	return true;
	    }
	    
	    //analysis the south west line
	    ax=x;
	    ay=y;
	    count=0;
	    while(ay < mapSize && ax >= 0 && chessMap[ax][ay] == chessMap[x][y]){
	    	count++;
	    	ay++;
	    	ax--;
	    }
	    ay=y;
	    ax=x;
	    count--;
	    while(ay > 0 && ax < mapSize && chessMap[ax][ay] == chessMap[x][y]){
	    	count++;
	    	ay--;
	    	ax++;
	    }
	    if(count>4){
	    	return true;
	    }
	    
		return false;
	}
	
	/**
	 * set game over
	 */
	void gameOver()
	{
		status = GameStatus.Over;
	}
}


/**
 * 
 * @author JiangLei
 * this class records the information about the player
 *
 */
class Player{
	public String playerName;
	public ChessMan chessMan;
	public PlayerStatusPanel playerPanel;

	Player(String name, ChessMan chessMan){
		playerName = name;
		this.chessMan = chessMan;
	}
}

/**
 * 
 * this class draws the game board and process player's interaction with it
 *
 */
class ChessPad extends JPanel implements MouseListener
{
	private static final long serialVersionUID = 1L;

	//game on this board
	ChessGame game;
	//the layout parameter of the board
	public final int locationX = 20;
	public final int locationY = 20;
	public final int width = 30;
	public final int sizeX;
	public final int sizeY;
	public int chessManRadius = 12;
	//the player who will interact with the board
	Player listeningPlayer;

	
	ChessPad(ChessGame g)
	{
		this.game = g;
		//set the appearance of the board
		this.setBackground(Color.orange);
		sizeX = (game.mapSize - 1) * width + 2 * locationX;
		sizeY = (game.mapSize - 1) * width + 2 * locationY;
		this.setSize(sizeX, sizeY);

		addMouseListener(this);	
	}
	
	/**
	 * 
	 * @param g		the graphics handler
	 * @param i		the x position of the chess 
	 * @param j		the y position of the chess
	 */
	private void drawChessMan(Graphics g, int i,int j)
	{
		//x,y: the coordinates on panel
		int x = i * width + locationX;
		int y = j * width + locationY;
		
        if(game.chessMap[i][j] == ChessMan.Black)
        {
        	//draw the outline
            g.setColor(Color.gray);
            g.drawOval(x - chessManRadius,y - chessManRadius,chessManRadius * 2, chessManRadius * 2);
           	//fill the center
            g.setColor(Color.BLACK);
            g.fillOval(x - chessManRadius,y - chessManRadius,chessManRadius * 2, chessManRadius * 2);
        }
		else if(game.chessMap[i][j] == ChessMan.White)
		{
			//draw the outline
			g.setColor(Color.gray);
			g.drawOval(x - chessManRadius,y - chessManRadius,chessManRadius * 2, chessManRadius * 2);
			//fill the center
			g.setColor(Color.white);
			g.fillOval(x - chessManRadius,y - chessManRadius,chessManRadius * 2, chessManRadius * 2);
		}
   	}
   
    public void paint(Graphics g)
    {
    	super.paint(g);
		
    	//draw the grid
		for (int i = 0; i < game.mapSize; i++)
		{
			g.drawLine(locationX, locationY + width * i, locationX + width * (game.mapSize - 1), locationY + width * i);
			g.drawLine(locationX + width * i, locationY, locationX + width * i, locationY + width * (game.mapSize - 1));
			
		}
		
		//draw the chess
		for(int i = 0; i < game.mapSize; i++)
		{
			for(int j = 0;j < game.mapSize; j++)
			{
				drawChessMan(g,i,j);
			}
		}
		
		//System.out.println("Paint() finished!");
 
	}
    
    public void mousePressed(MouseEvent e)
    {
		//System.out.println("Mouse Pressed!");
		if(game.status != GameStatus.Running)
			return;
		
    	if(listeningPlayer == game.activePlayer)
    	{	
    		//x, y: the position on board when mouse is pressed
		    int x = Math.round((float)(e.getX() - locationX) / (float)width);
		    int y = Math.round((float)(e.getY() - locationY) / (float)width);
		    
		    //if all conditions permits
		    if(x >= 0 && x < game.mapSize && y >= 0 && y < game.mapSize && game.activePlayer == this.listeningPlayer && game.chessMap[x][y] == ChessMan.Empty)
		    {
				//System.out.println("x:" + x + " " + "y:" + y);
		    	
		    	game.playChess(x, y);
		    	
		    	if(game.gameType == GameType.LocalGame)
		    	{
		    		//switch player
		    		listeningPlayer = game.activePlayer;
		    	}
		    	else if(game.gameType == GameType.NetGame)
		    	{
		    		//send the chess information to the other player
			    	try{
			    		game.sock.getOutputStream().write(x);
			    		game.sock.getOutputStream().write(y);
						System.out.println("Write stream finished!");
					}
	    			catch(IOException ex)
	    			{
	    				System.out.println("Write Error!");
	    			}
		    	}
		    	else if(game.gameType == GameType.ComputerGame)
		    	{
	    			game.AIThread.resume();
		    	}
		    	
		    }
    	}
    }
    
    public void mouseReleased(MouseEvent e){}    
    public void mouseEntered(MouseEvent e){}    
    public void mouseExited(MouseEvent e){}    
    public void mouseClicked(MouseEvent e){}

}

/**
 * 
 * this class draws the player status panel
 *
 */
class PlayerStatusPanel extends JPanel
{
	private static final long serialVersionUID = 1L;
	
	//the appearance parameter
	static final int width = 200;
	static final int height = 80;
	static final int chessManPosX = 20;
	static final int chessManPosY = 30;
	
	//player on this panel
	Player player;
	//label which shows the time left
	JLabel timeLabel;
	public int timeLeftInSeconds;
	Timer chessTimer;
	ChessGame game;
	
	PlayerStatusPanel(Player pl, int seconds, ChessGame g)
	{
		this.player = pl;
		this.game = g;
		this.timeLeftInSeconds = seconds;
		//set the layout of this panel
		this.setBackground(Color.yellow);
		this.setSize(PlayerStatusPanel.width, PlayerStatusPanel.height);
		setLayout(new BorderLayout());
		JLabel nameLb = new JLabel("玩家名称:" + player.playerName);
		JPanel p = new JPanel();
		p.setBackground(Color.yellow);
		p.setLayout(new GridLayout(2, 1));
		p.add(nameLb);
		p.setSize(width - 2 * chessManPosX, height);
		timeLabel = new JLabel("所剩时间:" + seconds/60 + ":" + seconds%60);
		p.add(timeLabel);
		add("East", p);

		//add Timer
		chessTimer = new Timer(1000, new ActionListener(){
			public void actionPerformed(ActionEvent e)
			{
				if(game.status != GameStatus.Running)
					chessTimer.stop();
				timeLeftInSeconds--;
				timeLabel.setText("所剩时间:" + timeLeftInSeconds/60 + ":" + timeLeftInSeconds%60);
				if(timeLeftInSeconds == 0)
				{	//超时判负
					game.gameOver();
					String s = player.playerName + "超时判负";
					GameResultDialog d = new GameResultDialog(MainFrame.mainFrame, 100, 100, s); 
					d.setVisible(true);
				}
			}
		});
	}
	
	/**
	 * this method paint this panel
	 * 
	 */
	public void paint(Graphics g)
	{
		super.paint(g);
		//refresh the label
		timeLabel.setText("所剩时间:" + timeLeftInSeconds/60 + ":" + timeLeftInSeconds%60);
		//paint the chess indicates the side
		g.setColor(Color.gray);
		g.drawOval(chessManPosX, chessManPosY, game.cpad.chessManRadius * 2, game.cpad.chessManRadius * 2);
        if(player.chessMan == ChessMan.Black)
        {
           	g.setColor(Color.BLACK);
        }
		else 
		{
			g.setColor(Color.white);
		}		
		g.fillOval(chessManPosX, chessManPosY, game.cpad.chessManRadius * 2, game.cpad.chessManRadius * 2);
	}

}

/**
 * 
 * this class is a dialog, it will show the result of the game
 *
 */
class GameResultDialog extends JDialog
{
	GameResultDialog(JFrame parent, int w, int h, String resultStr)
	{
		super(parent, "本局结果", true);
		setSize(w, h);
		setLocation(500, 300);
		
		setLayout(new FlowLayout());
		JLabel lb = new JLabel(resultStr);
		JButton bn = new JButton("确定");
		add("North", lb);
		add("South", bn);
		
		bn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e)
			{
				MainFrame.mainFrame.startGameBn.setEnabled(true);
				setVisible(false);
			}
		});
		
		addWindowListener(new WindowAdapter()
        {public void windowClosing(WindowEvent e)
             {
				MainFrame.mainFrame.startGameBn.setEnabled(true);
        		setVisible(false);
        		}
             });
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -