package com.wzq;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RadialGradientPaint;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Ellipse2D;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
public class WZQTest extends JFrame{
private static final long serialVersionUID = 1L;
private static int Rows = 15;
private static int Cols = 15;
private static int Grap = 30;
private boolean flagX = false;
private boolean flagY = false;
private boolean selPoint = false;
private Point selChessPoint = new Point(0,0,Color.black);
private Point[] chessPoint = new Point[(Rows+1)*(Cols+1)];
private int curChessPointNum = 0;
private boolean isBlack = true;
private boolean gameOver = false;
private jpQP jpQp = null;
JMenuItem jBack = null;
JMenuItem jRestar = null;
JMenuItem jExit = null;
public WZQTest(){
setTitle("五子棋");
jpQp = new jpQP();
jpQp.setOpaque(true);
add(jpQp);
JMenuBar jMenuBar = new JMenuBar();
JMenu jMenu = new JMenu("文件(F)");
jMenu.setMnemonic(KeyEvent.VK_F);
jBack = new JMenuItem("悔棋(Z)",KeyEvent.VK_Z);
jRestar = new JMenuItem("重新开始(R)",KeyEvent.VK_R);
jExit = new JMenuItem("退出(Q)",KeyEvent.VK_Q);
jBack.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Z,InputEvent.CTRL_MASK));
jRestar.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_R,InputEvent.CTRL_MASK));
jExit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q,InputEvent.CTRL_MASK));
jBack.addActionListener(new JChessMenuEvent());
jRestar.addActionListener(new JChessMenuEvent());
jExit.addActionListener(new JChessMenuEvent());
jMenu.add(jBack);
jMenu.add(jRestar);
jMenu.add(jExit);
jMenuBar.add(jMenu);
setJMenuBar(jMenuBar);
setResizable(false);
setLocation(Toolkit.getDefaultToolkit().getScreenSize().width/2-260,Toolkit.getDefaultToolkit().getScreenSize().height/2-290);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setPreferredSize(new Dimension(530,570));
setVisible(true);
pack();
}
private class Point{
private int x;//棋盘中的x索引
private int y;//棋盘中的y索引
private Color color;//颜色
public Point(int x,int y,Color color){
this.x=x;
this.y=y;
this.color=color;
}
public int getX(){//拿到棋盘中x的索引
return x;
}
public int getY(){
return y;
}
public Color getColor(){//获得棋子的颜色
return color;
}
/**
* @param x the x to set
*/
public void setX(int x) {
this.x = x;
}
/**
* @param y the y to set
*/
public void setY(int y) {
this.y = y;
}
/**
* @param color the color to set
*/
public void setColor(Color color) {
this.color = color;
}
}
private class JChessMenuEvent implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
if(jBack == e.getSource()){
if(curChessPointNum == 0){
return;
}
selPoint = false;
chessPoint[--curChessPointNum] = null;
isBlack = !isBlack;
gameOver = false;
repaint();
}else if(jRestar == e.getSource()){
for(int i=0;i<chessPoint.length;i++){
chessPoint[i] = null;
}
selPoint = false;
curChessPointNum = 0;
isBlack = true;
gameOver = false;
repaint();
}else{
System.exit(0);
}
}
}
private class jpQP extends JPanel{
private static final long serialVersionUID = 1L;
public jpQP(){
addMouseMotionListener(new MouseMotionListener() {
@Override
public void mouseMoved(MouseEvent e) {
if(gameOver){
return;
}
if((e.getX()-Grap/3*2)%Grap <=Grap/3*2 && (e.getX()-Grap/3*2)%Grap <=Grap/3*2 && e.getX()>=Grap/3*2 && e.getX()<= (Grap+Grap*Cols+Grap/3)){
flagX = true;
}else{
flagX = false;
}
if((e.getY()-Grap/3*2)%Grap <=Grap/3*2 && (e.getY()-Grap/3*2)%Grap <=Grap/3*2 && e.getY()>=Grap/3*2 && e.getY()<= (Grap+Grap*Rows+Grap/3)){
flagY = true;
}else{
flagY = false;
}
if(flagX&&flagY){
setCursor(new Cursor(Cursor.HAND_CURSOR));
selChessPoint.setX((e.getX()-Grap/2)/Grap);
selChessPoint.setY((e.getY()-Grap/2)/Grap);
selChessPoint.setColor(isBlack?Color.black:Color.white);
selPoint = true;
repaint();
}else{
setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
selPoint = false;
repaint();
}
}
@Override
public void mouseDragged(MouseEvent mouseevent) {
}
});
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
if(gameOver){
return;
}
//有效区域
if(flagX&&flagY){
String colorName=isBlack?"黑棋":"白棋";
boolean addChess = false;
if(curChessPointNum == 0){
chessPoint[curChessPointNum++] = new Point(selChessPoint.getX(),selChessPoint.getY(),selChessPoint.getColor());
isBlack = !isBlack;
addChess = true;
repaint();
}else if(!findChess(selChessPoint)){
chessPoint[curChessPointNum++] = new Point(selChessPoint.getX(),selChessPoint.getY(),selChessPoint.getColor());
isBlack = !isBlack;
addChess = true;
repaint();
}
if(addChess && isWin()){
String msg=String.format("恭喜,%s赢了!", colorName);
JOptionPane.showMessageDialog(WZQTest.this, msg);
gameOver=true;;
}
}
}
});
}
private boolean isWin() {
int curXNum = chessPoint[curChessPointNum-1].getX();
int curYNum = chessPoint[curChessPointNum-1].getY();
int curChessNum = 1;
//横向
for(int Xi=curXNum+1;Xi<Cols;Xi++){
if(getChessPoint(Xi,curYNum,chessPoint[curChessPointNum-1].getColor())){
curChessNum++;
}else{
break;
}
}
for(int Xi=curXNum-1;Xi>=0;Xi--){
if(getChessPoint(Xi,curYNum,chessPoint[curChessPointNum-1].getColor())){
curChessNum++;
}else{
break;
}
}
if(curChessNum >= 5){
return true;
}
//纵向
curChessNum = 1;
for(int Yi=curYNum+1;Yi<Rows;Yi++){
if(getChessPoint(curXNum,Yi,chessPoint[curChessPointNum-1].getColor())){
curChessNum++;
}else{
break;
}
}
for(int Yi=curYNum-1;Yi>=0;Yi--){
if(getChessPoint(curXNum,Yi,chessPoint[curChessPointNum-1].getColor())){
curChessNum++;
}else{
break;
}
}
if(curChessNum >= 5){
return true;
}
//方向\
curChessNum = 1;
for(int Xi=curXNum+1,Yi=curYNum+1;Xi<Cols&&Yi<Rows;Xi++,Yi++){
if(getChessPoint(Xi,Yi,chessPoint[curChessPointNum-1].getColor())){
curChessNum++;
}else{
break;
}
}
for(int Xi=curXNum-1,Yi=curYNum-1;Xi>=0&&Yi>=0;Xi++,Yi++){
if(getChessPoint(Xi,Yi,chessPoint[curChessPointNum-1].getColor())){
curChessNum++;
}else{
break;
}
}
if(curChessNum >= 5){
return true;
}
//方向/
curChessNum = 1;
for(int Xi=curXNum+1,Yi=curYNum-1;Xi<Cols&&Yi>=0;Xi++,Yi--){
if(getChessPoint(Xi,Yi,chessPoint[curChessPointNum-1].getColor())){
curChessNum++;
}else{
break;
}
}
for(int Xi=curXNum-1,Yi=curYNum+1;Xi>=0&&Yi<Rows;Xi--,Yi++){
if(getChessPoint(Xi,Yi,chessPoint[curChessPointNum-1].getColor())){
curChessNum++;
}else{
break;
}
}
if(curChessNum >= 5){
return true;
}
return false;
}
private boolean getChessPoint(int curXPosNum, int curYPosNum,Color color) {
for(int i=0;i<curChessPointNum;i++){
if(curXPosNum == chessPoint[i].getX() && curYPosNum == chessPoint[i].getY() && color == chessPoint[i].getColor()){
return true;
}
}
return false;
}
private boolean findChess(Point p){
for(int i=0;i<curChessPointNum;i++){
if(p.getX() == chessPoint[i].getX() && p.getY() == chessPoint[i].getY() ){
return true;
}
}
return false;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for(int i=0;i<=Rows;i++){
g.drawLine(Grap, Grap+i*Grap, Grap+Grap*Rows, Grap+i*Grap);
}
for(int i=0;i<=Cols;i++){
g.drawLine(Grap+i*Grap, Grap, Grap+i*Grap, Grap+Grap*Cols);
}
for(int i=0;i<curChessPointNum;i++){
g.setColor(chessPoint[i].getColor());
int xPos=chessPoint[i].getX()*Grap;
int yPos=chessPoint[i].getY()*Grap;
RadialGradientPaint paint = new RadialGradientPaint(xPos+Grap/2+25, yPos+Grap/2+10, chessPoint[i].getColor() == Color.black?20:70, new float[]{0f, 1f}
, new Color[]{Color.WHITE, Color.black});
((Graphics2D) g).setPaint(paint);
((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT);
Ellipse2D e = new Ellipse2D.Float(xPos+Grap/2, yPos+Grap/2, Grap, Grap);
((Graphics2D) g).fill(e);
if(i == curChessPointNum-1){
g.setColor(Color.red);
g.drawRect(xPos+Grap/2, yPos+Grap/2, Grap, Grap);
}
}
if(selPoint && !findChess(selChessPoint)){
g.setColor(selChessPoint.getColor());
int xPos=selChessPoint.getX()*Grap;
int yPos=selChessPoint.getY()*Grap;
RadialGradientPaint paint = new RadialGradientPaint(xPos+Grap/2+25, yPos+Grap/2+10, selChessPoint.getColor() == Color.black?20:70, new float[]{0f, 1f}
, new Color[]{Color.WHITE, Color.black});
((Graphics2D) g).setPaint(paint);
((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT);
Ellipse2D e = new Ellipse2D.Float(xPos+Grap/2, yPos+Grap/2, Grap, Grap);
((Graphics2D) g).fill(e);
}
}
}
public static void main(String[] args) {
new WZQTest();
}
}