闲来无事 化了n(n<3)个小时作了个围棋对战程序 比较清爽的说 典型的MVC结构
//Main.java
package go;
public class Main {
public Main() {
}
public static void main(String[] args) {
MainWindow mw = new MainWindow();
mw.setResizable(false);
mw.setTitle("GO --- 胜负!!!");
mw.setSize(545,590);
mw.setVisible(true);
}
}
//MainWindow.java
package go;
import java.awt.*;
import java.awt.event.*;
public class MainWindow extends Frame implements ActionListener{
/** Creates new form MainWindow */
public MainWindow() {
initEvent();
initMenu();
initComponents();
}
private void initEvent() {
this.addWindowListener(new WindowEventListener());
}
private void initMenu() {
mb = new MenuBar();
file = new Menu("文件");
edit = new Menu("编辑");
menu_exit = new MenuItem("退出");
menu_new = new MenuItem("新局");
menu_undo = new MenuItem("撤销");
menu_redo = new MenuItem("重做");
menu_exit.addActionListener(this);
menu_new.addActionListener(this);
menu_undo.addActionListener(this);
menu_redo.addActionListener(this);
file.add(menu_new);
file.addSeparator();
file.add(menu_exit);
edit.add(menu_undo);
edit.add(menu_redo);
mb.add(file);
mb.add(edit);
}
private void initComponents() {
gp = new goPanel();
gp.setSize(100,100);
setLayout(new java.awt.GridLayout());
this.add(gp);
this.setMenuBar(mb);
pack();
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == menu_new) gp.newRound();
else if (e.getSource() == menu_exit) System.exit(0);
else if (e.getSource() == menu_undo) gp.undo();
else if (e.getSource() == menu_redo) gp.redo();
}
private goPanel gp;
private MenuBar mb;
private Menu file;
private MenuItem menu_exit;
private MenuItem menu_new;
private Menu edit;
private MenuItem menu_undo;
private MenuItem menu_redo;
}
class WindowEventListener implements WindowListener {
public void windowOpened(WindowEvent e) {}
public void windowClosing(WindowEvent e) {
System.exit(1);
}
public void windowIconified(WindowEvent e) {}
public void windowDeiconified(WindowEvent e) {}
public void windowActivated(WindowEvent e) {}
public void windowDeactivated(WindowEvent e) {}
}
//goPanel.java
package go;
import java.awt.*;
import java.awt.event.*;
public class goPanel extends Panel implements MouseWheelListener{
public final int WHITECHESSMAN = 1;
public final int BLACKCHESSMAN = 2;
private GoModel gm;
public goPanel() {
gm = new GoModel(this);
this.addMouseListener(new MouseEventListener(gm));
this.addMouseWheelListener(this);
}
public void newRound() {
gm.newRound();
}
public void DrawChessman(int x,int y,int state) {
Graphics g;
g = this.getGraphics();
switch(state) {
case 0:
g.setColor(Color.WHITE);
g.fillOval(x*30 - 12 , y* 30 - 12 , 24,24);
DrawPanel(g,x*30 - 12 , y* 30 - 12 , 24,24);
break;
case WHITECHESSMAN:
g.setColor(Color.WHITE);
g.fillOval(x*30 - 10 , y* 30 - 10 , 20,20);
g.setColor(Color.BLACK);
g.drawOval(x*30 - 10 , y* 30 - 10 , 20,20);
break;
case BLACKCHESSMAN:
g.fillOval(x*30 - 10 , y* 30 - 10 , 20,20);
g.drawOval(x*30 - 10 , y* 30 - 10 , 20,20);
break;
}
g.setColor(Color.BLACK);
}
public void DrawPanel(Graphics g) {
int i;
g.setColor(Color.GRAY.brighter());
for (i=1;i<=17;i++)
g.drawLine(i*30,0,i*30,getSize().height);
for (i=1;i<=17;i++)
g.drawLine(0,i*30,getSize().width,i*30);
g.fillOval(4*30-5,4*30-5,10,10);
g.fillOval(14*30-5,14*30-5,10,10);
g.fillOval(9*30-5,9*30-5,10,10);
g.fillOval(4*30-5,14*30-5,10,10);
g.fillOval(14*30-5,4*30-5,10,10);
g.setColor(Color.BLACK);
}
public void DrawPanel(Graphics g,int x,int y,int w,int h) {
g.clipRect(x,y,w,h);
DrawPanel(g);
}
public void paint(Graphics g) {
//g.draw3DRect(5,5,this.getSize().width-6,this.getSize().height-6,false);
int i,j;
DrawPanel(g);
for (i=1;i<=17;i++)
for (j=1;j<=17;j++)
DrawChessman(i,j,gm.getData(i-1,j-1));
}
public void updateUI () {
this.repaint();
}
public void undo() {
gm.undo();
}
public void redo() {
gm.redo();
}
public void mouseWheelMoved(MouseWheelEvent e) {
if (e.getWheelRotation() > 0) undo(); else redo();
}
}
class MouseEventListener implements MouseListener {
private GoModel gm;
public MouseEventListener(GoModel arg) {
gm = arg;
}
public void mouseClicked(MouseEvent e) { }
public void mousePressed(MouseEvent e) { }
public void mouseReleased(MouseEvent e) {
Point p = e.getPoint();
int x = (p.x - 10) / 30;
int y = (p.y - 10) / 30;
switch (e.getButton()) {
case MouseEvent.BUTTON1:
gm.setChessMan(x,y);
break;
}
}
public void mouseEntered(MouseEvent e) { }
public void mouseExited(MouseEvent e) {}
}
//goModel.java
package go;
import java.util.*;
public class GoModel {
class ChessMan {
public int state;
public boolean tag;
}
private Vector histroy;
private int current;
private histroyNode record;
private ChessMan[][] data;
private boolean side = true;
private goPanel gp;
public GoModel(goPanel g) {
int i,j;
gp = g;
data = new ChessMan[19][];
for (i=0;i<19;i++)
{
data[i] = new ChessMan[19];
for (j=0;j<19;j++)
data[i][j] = new ChessMan();
}
histroy = new Vector();
record = new histroyNode(side);
}
public void setChessMan(int x,int y) {
if (x<0 || x>16 || y<0 || y>16) return;
if (data[x][y].state != 0) return;
if (histroy.size() != current)
while(histroy.size() != current) histroy.removeElementAt(histroy.size()-1);
data[x][y].state = side?gp.WHITECHESSMAN:gp.BLACKCHESSMAN;
clearDeadChessman(x,y);
if (!hasBlockWithoutSelf(x,y,side?gp.WHITECHESSMAN:gp.BLACKCHESSMAN)) {data[x][y].state = 0;return;}
data[x][y].state = 0;
drawChessMan(x,y,side?gp.WHITECHESSMAN:gp.BLACKCHESSMAN);
side = !side;
histroy.add(record);
record = new histroyNode(side);
current++;
}
public void drawChessMan(int x,int y,int state) {
if (state == 0) record.addData(x,y,data[x][y].state,false); else record.addData(x,y,state,true);
data[x][y].state = state;
gp.DrawChessman(x+1,y+1,state);
}
public int getData(int x,int y) {
return data[x][y].state;
}
private boolean hasBlock (int x,int y,int side) {
if (x<0 || x>16 || y<0 || y>16) return false;
if (data[x][y].state == 0) return true;
if (data[x][y].state != side) return false;
if (data[x][y].tag == true) return false; else data[x][y].tag = true;
System.out.println("hasBlock: x=" + x + ",y=" + y + ",State=" + data[x][y].state);
if (hasBlock(x-1,y,side)) return true;
if (hasBlock(x+1,y,side)) return true;
if (hasBlock(x,y-1,side)) return true;
if (hasBlock(x,y+1,side)) return true;
return false;
}
private boolean hasBlockWithoutSelf (int x,int y,int side) {
if (x<0 || x>17 || y<0 || y>17) return false;
data[x][y].tag = true;
if (data[x][y].state != side) return true;
if (hasBlock(x-1,y,side)) return true;
if (hasBlock(x+1,y,side)) return true;
if (hasBlock(x,y-1,side)) return true;
if (hasBlock(x,y+1,side)) return true;
return false;
}
private void clearDeadChessman(int x,int y) {
clearTag();
if (!hasBlockWithoutSelf(x-1,y,!side?gp.WHITECHESSMAN:gp.BLACKCHESSMAN)) clearDataWithTag();
clearTag();
if (!hasBlockWithoutSelf(x+1,y,!side?gp.WHITECHESSMAN:gp.BLACKCHESSMAN)) clearDataWithTag();
clearTag();
if (!hasBlockWithoutSelf(x,y-1,!side?gp.WHITECHESSMAN:gp.BLACKCHESSMAN)) clearDataWithTag();
clearTag();
if (!hasBlockWithoutSelf(x,y+1,!side?gp.WHITECHESSMAN:gp.BLACKCHESSMAN)) clearDataWithTag();
}
public void clearTag() {
int i,j;
for (i=0;i<17;i++)
for (j=0;j<17;j++)
data[i][j].tag = false;
}
public void clearDataWithTag() {
int i,j;
for (i=0;i<17;i++)
for (j=0;j<17;j++)
if (data[i][j].tag == true) {
drawChessMan(i,j,0);
data[i][j].tag = false;
}
}
public void newRound() {
int i,j;
for (i=0;i<17;i++)
for (j=0;j<17;j++)
data[i][j].state = 0;
gp.repaint();
histroy.clear();
current = 0;
side = true;
}
public void undo() {
int i;
if (current == 0) return;
histroyNode hn = (histroyNode)histroy.get(current-1);
histroyData hd;
side = !side;
for (i=0;i<hn.getDataSize();i++) {
hd = hn.getData(i);
if (hd.isSet)
drawChessMan(hd.x,hd.y,0);
else
drawChessMan(hd.x,hd.y,hd.state);
}
record.clear();
current--;
}
public void redo() {
int i;
if (histroy.size() == current) return;
histroyNode hn = (histroyNode)histroy.get(current);
histroyData hd;
side = !side;
for (i=0;i<hn.getDataSize();i++) {
hd = hn.getData(i);
if (!hd.isSet)
drawChessMan(hd.x,hd.y,0);
else
drawChessMan(hd.x,hd.y,hd.state);
}
current++;
}
}
class histroyData {
public int x;
public int y;
public int state;
public boolean isSet;
public histroyData(int i,int j) {x = i;y = j;}
public histroyData(int i,int j,int set,boolean b) {x = i;y = j;state = set;isSet = b;}
}
class histroyNode {
private Vector data;
private boolean side;
public histroyNode(boolean b) {
data = new Vector();
side = b;
}
public boolean getSide() {
return side;
}
public histroyData getData(int i) {
return ((histroyData)data.get(i));
}
public void setData(int i,int x,int y,int set) {
histroyData p = (histroyData)data.get(i);
p.x = x;
p.y = y;
p.state = set;
}
public void addData(int x,int y,int set,boolean s) {
histroyData p = new histroyData(x,y,set,s);
data.add(p);
}
public int getDataSize() {
return data.size();
}
public void clear() {
data.clear();
}
}
//Main.java
package go;
public class Main {
public Main() {
}
public static void main(String[] args) {
MainWindow mw = new MainWindow();
mw.setResizable(false);
mw.setTitle("GO --- 胜负!!!");
mw.setSize(545,590);
mw.setVisible(true);
}
}
//MainWindow.java
package go;
import java.awt.*;
import java.awt.event.*;
public class MainWindow extends Frame implements ActionListener{
/** Creates new form MainWindow */
public MainWindow() {
initEvent();
initMenu();
initComponents();
}
private void initEvent() {
this.addWindowListener(new WindowEventListener());
}
private void initMenu() {
mb = new MenuBar();
file = new Menu("文件");
edit = new Menu("编辑");
menu_exit = new MenuItem("退出");
menu_new = new MenuItem("新局");
menu_undo = new MenuItem("撤销");
menu_redo = new MenuItem("重做");
menu_exit.addActionListener(this);
menu_new.addActionListener(this);
menu_undo.addActionListener(this);
menu_redo.addActionListener(this);
file.add(menu_new);
file.addSeparator();
file.add(menu_exit);
edit.add(menu_undo);
edit.add(menu_redo);
mb.add(file);
mb.add(edit);
}
private void initComponents() {
gp = new goPanel();
gp.setSize(100,100);
setLayout(new java.awt.GridLayout());
this.add(gp);
this.setMenuBar(mb);
pack();
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == menu_new) gp.newRound();
else if (e.getSource() == menu_exit) System.exit(0);
else if (e.getSource() == menu_undo) gp.undo();
else if (e.getSource() == menu_redo) gp.redo();
}
private goPanel gp;
private MenuBar mb;
private Menu file;
private MenuItem menu_exit;
private MenuItem menu_new;
private Menu edit;
private MenuItem menu_undo;
private MenuItem menu_redo;
}
class WindowEventListener implements WindowListener {
public void windowOpened(WindowEvent e) {}
public void windowClosing(WindowEvent e) {
System.exit(1);
}
public void windowIconified(WindowEvent e) {}
public void windowDeiconified(WindowEvent e) {}
public void windowActivated(WindowEvent e) {}
public void windowDeactivated(WindowEvent e) {}
}
//goPanel.java
package go;
import java.awt.*;
import java.awt.event.*;
public class goPanel extends Panel implements MouseWheelListener{
public final int WHITECHESSMAN = 1;
public final int BLACKCHESSMAN = 2;
private GoModel gm;
public goPanel() {
gm = new GoModel(this);
this.addMouseListener(new MouseEventListener(gm));
this.addMouseWheelListener(this);
}
public void newRound() {
gm.newRound();
}
public void DrawChessman(int x,int y,int state) {
Graphics g;
g = this.getGraphics();
switch(state) {
case 0:
g.setColor(Color.WHITE);
g.fillOval(x*30 - 12 , y* 30 - 12 , 24,24);
DrawPanel(g,x*30 - 12 , y* 30 - 12 , 24,24);
break;
case WHITECHESSMAN:
g.setColor(Color.WHITE);
g.fillOval(x*30 - 10 , y* 30 - 10 , 20,20);
g.setColor(Color.BLACK);
g.drawOval(x*30 - 10 , y* 30 - 10 , 20,20);
break;
case BLACKCHESSMAN:
g.fillOval(x*30 - 10 , y* 30 - 10 , 20,20);
g.drawOval(x*30 - 10 , y* 30 - 10 , 20,20);
break;
}
g.setColor(Color.BLACK);
}
public void DrawPanel(Graphics g) {
int i;
g.setColor(Color.GRAY.brighter());
for (i=1;i<=17;i++)
g.drawLine(i*30,0,i*30,getSize().height);
for (i=1;i<=17;i++)
g.drawLine(0,i*30,getSize().width,i*30);
g.fillOval(4*30-5,4*30-5,10,10);
g.fillOval(14*30-5,14*30-5,10,10);
g.fillOval(9*30-5,9*30-5,10,10);
g.fillOval(4*30-5,14*30-5,10,10);
g.fillOval(14*30-5,4*30-5,10,10);
g.setColor(Color.BLACK);
}
public void DrawPanel(Graphics g,int x,int y,int w,int h) {
g.clipRect(x,y,w,h);
DrawPanel(g);
}
public void paint(Graphics g) {
//g.draw3DRect(5,5,this.getSize().width-6,this.getSize().height-6,false);
int i,j;
DrawPanel(g);
for (i=1;i<=17;i++)
for (j=1;j<=17;j++)
DrawChessman(i,j,gm.getData(i-1,j-1));
}
public void updateUI () {
this.repaint();
}
public void undo() {
gm.undo();
}
public void redo() {
gm.redo();
}
public void mouseWheelMoved(MouseWheelEvent e) {
if (e.getWheelRotation() > 0) undo(); else redo();
}
}
class MouseEventListener implements MouseListener {
private GoModel gm;
public MouseEventListener(GoModel arg) {
gm = arg;
}
public void mouseClicked(MouseEvent e) { }
public void mousePressed(MouseEvent e) { }
public void mouseReleased(MouseEvent e) {
Point p = e.getPoint();
int x = (p.x - 10) / 30;
int y = (p.y - 10) / 30;
switch (e.getButton()) {
case MouseEvent.BUTTON1:
gm.setChessMan(x,y);
break;
}
}
public void mouseEntered(MouseEvent e) { }
public void mouseExited(MouseEvent e) {}
}
//goModel.java
package go;
import java.util.*;
public class GoModel {
class ChessMan {
public int state;
public boolean tag;
}
private Vector histroy;
private int current;
private histroyNode record;
private ChessMan[][] data;
private boolean side = true;
private goPanel gp;
public GoModel(goPanel g) {
int i,j;
gp = g;
data = new ChessMan[19][];
for (i=0;i<19;i++)
{
data[i] = new ChessMan[19];
for (j=0;j<19;j++)
data[i][j] = new ChessMan();
}
histroy = new Vector();
record = new histroyNode(side);
}
public void setChessMan(int x,int y) {
if (x<0 || x>16 || y<0 || y>16) return;
if (data[x][y].state != 0) return;
if (histroy.size() != current)
while(histroy.size() != current) histroy.removeElementAt(histroy.size()-1);
data[x][y].state = side?gp.WHITECHESSMAN:gp.BLACKCHESSMAN;
clearDeadChessman(x,y);
if (!hasBlockWithoutSelf(x,y,side?gp.WHITECHESSMAN:gp.BLACKCHESSMAN)) {data[x][y].state = 0;return;}
data[x][y].state = 0;
drawChessMan(x,y,side?gp.WHITECHESSMAN:gp.BLACKCHESSMAN);
side = !side;
histroy.add(record);
record = new histroyNode(side);
current++;
}
public void drawChessMan(int x,int y,int state) {
if (state == 0) record.addData(x,y,data[x][y].state,false); else record.addData(x,y,state,true);
data[x][y].state = state;
gp.DrawChessman(x+1,y+1,state);
}
public int getData(int x,int y) {
return data[x][y].state;
}
private boolean hasBlock (int x,int y,int side) {
if (x<0 || x>16 || y<0 || y>16) return false;
if (data[x][y].state == 0) return true;
if (data[x][y].state != side) return false;
if (data[x][y].tag == true) return false; else data[x][y].tag = true;
System.out.println("hasBlock: x=" + x + ",y=" + y + ",State=" + data[x][y].state);
if (hasBlock(x-1,y,side)) return true;
if (hasBlock(x+1,y,side)) return true;
if (hasBlock(x,y-1,side)) return true;
if (hasBlock(x,y+1,side)) return true;
return false;
}
private boolean hasBlockWithoutSelf (int x,int y,int side) {
if (x<0 || x>17 || y<0 || y>17) return false;
data[x][y].tag = true;
if (data[x][y].state != side) return true;
if (hasBlock(x-1,y,side)) return true;
if (hasBlock(x+1,y,side)) return true;
if (hasBlock(x,y-1,side)) return true;
if (hasBlock(x,y+1,side)) return true;
return false;
}
private void clearDeadChessman(int x,int y) {
clearTag();
if (!hasBlockWithoutSelf(x-1,y,!side?gp.WHITECHESSMAN:gp.BLACKCHESSMAN)) clearDataWithTag();
clearTag();
if (!hasBlockWithoutSelf(x+1,y,!side?gp.WHITECHESSMAN:gp.BLACKCHESSMAN)) clearDataWithTag();
clearTag();
if (!hasBlockWithoutSelf(x,y-1,!side?gp.WHITECHESSMAN:gp.BLACKCHESSMAN)) clearDataWithTag();
clearTag();
if (!hasBlockWithoutSelf(x,y+1,!side?gp.WHITECHESSMAN:gp.BLACKCHESSMAN)) clearDataWithTag();
}
public void clearTag() {
int i,j;
for (i=0;i<17;i++)
for (j=0;j<17;j++)
data[i][j].tag = false;
}
public void clearDataWithTag() {
int i,j;
for (i=0;i<17;i++)
for (j=0;j<17;j++)
if (data[i][j].tag == true) {
drawChessMan(i,j,0);
data[i][j].tag = false;
}
}
public void newRound() {
int i,j;
for (i=0;i<17;i++)
for (j=0;j<17;j++)
data[i][j].state = 0;
gp.repaint();
histroy.clear();
current = 0;
side = true;
}
public void undo() {
int i;
if (current == 0) return;
histroyNode hn = (histroyNode)histroy.get(current-1);
histroyData hd;
side = !side;
for (i=0;i<hn.getDataSize();i++) {
hd = hn.getData(i);
if (hd.isSet)
drawChessMan(hd.x,hd.y,0);
else
drawChessMan(hd.x,hd.y,hd.state);
}
record.clear();
current--;
}
public void redo() {
int i;
if (histroy.size() == current) return;
histroyNode hn = (histroyNode)histroy.get(current);
histroyData hd;
side = !side;
for (i=0;i<hn.getDataSize();i++) {
hd = hn.getData(i);
if (!hd.isSet)
drawChessMan(hd.x,hd.y,0);
else
drawChessMan(hd.x,hd.y,hd.state);
}
current++;
}
}
class histroyData {
public int x;
public int y;
public int state;
public boolean isSet;
public histroyData(int i,int j) {x = i;y = j;}
public histroyData(int i,int j,int set,boolean b) {x = i;y = j;state = set;isSet = b;}
}
class histroyNode {
private Vector data;
private boolean side;
public histroyNode(boolean b) {
data = new Vector();
side = b;
}
public boolean getSide() {
return side;
}
public histroyData getData(int i) {
return ((histroyData)data.get(i));
}
public void setData(int i,int x,int y,int set) {
histroyData p = (histroyData)data.get(i);
p.x = x;
p.y = y;
p.state = set;
}
public void addData(int x,int y,int set,boolean s) {
histroyData p = new histroyData(x,y,set,s);
data.add(p);
}
public int getDataSize() {
return data.size();
}
public void clear() {
data.clear();
}
}