当前位置: 代码迷 >> Java相关 >> [求助] 五子棋程序达不到预期的效果
  详细解决方案

[求助] 五子棋程序达不到预期的效果

热度:307   发布时间:2006-12-25 02:16:13.0
[求助] 五子棋程序达不到预期的效果
小弟是新手,最近做了个五子棋(人人),先运行winandpanduan.java 接着运行 Game.java.程序能运行.但说有些东西是旧的,但达不到预期的效果.比如:winandpanduan类我只想初始化一次,以后就可以使用.想要的效果是,当出现五子连珠时弹一个对话框.
搜索更多相关的解决方案: 五子棋  效果  java  对话框  

----------------解决方案--------------------------------------------------------
怎么上附件啊.难啊

----------------解决方案--------------------------------------------------------

贴上来.
Game.java

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.geom.*;
import java.util.*;
//程序与winandpanduan连接用来判断五子连珠
class PaintPanel extends JPanel {
ArrayList Items = new ArrayList(100);//构造一个初始容量为 10 的空列表
boolean isMy;
public PaintPanel() { //布局
setLayout(new BorderLayout());
ButtonPanel buttonPanel = new ButtonPanel();//按钮,具有重画和推出功能
ButtonPanel2 buttonPanel2 = new ButtonPanel2();
add(buttonPanel, BorderLayout.SOUTH);//按钮在筐件下面
add(buttonPanel2,BorderLayout.NORTH);
addMouseListener(new MouseHandler());//增加事件 另外用一个类来说明事件与45行的函数对应(参考书215页)
}

public void paintComponent(Graphics g) {//只是重画这个容器
int startX = 50;
int startY = 50; //从屏幕的(50,50)开始画
isMy = false;//用于判断黑白棋
super.paintComponent(g);//重画时清屏
Graphics2D g2 = (Graphics2D)g;

for(int i=0; i<16; i++) {//生成棋盘17*17
g2.draw(new Line2D.Double(startX, startY+20*i, startX+300, startY+20*i));//画横线
g2.draw(new Line2D.Double(startX+20*i, startY, startX+20*i, startY+300));//画竖线
}

for(int i=0; i<Items.size(); i++) {//黑白棋交替出现
isMy = !isMy;
if(isMy)
g2.setColor(Color.BLACK);//真为黑
else
g2.setColor(Color.WHITE);//假为白
g2.fill((Ellipse2D)Items.get(i));//,对鼠标的控件生成的图形填充颜色
}
}

void myRepaint() {
repaint();//重画这个组件PaintPanel
}

private class MouseHandler extends MouseAdapter {
//鼠标事件使用户能够跟踪鼠标何时按下、释放、单击、进入组件和离开组件
winandpanduan win;
public void mousePressed(MouseEvent event) { //鼠标按下的事件
int x = event.getX();
int y = event.getY();
int j = (x-50)/20;
int k = (y-50)/20;
paintItem(x, y); //对鼠标点的地方标记
if (isMy==true) {
if(win.setpointblack(j,k)==true) JOptionPane.showMessageDialog( null, "black win!" );
}
else
{
if(win.setpointwrite(j,k)==true) JOptionPane.showMessageDialog( null, "black win!" );
}
repaint();
}
void paintItem(int x, int y) {//对鼠标点的地方标记
if(x >= 50 && x <= 350 && y >= 50 && y <= 350) {
int X = x / 20;
int Y = y / 20;
int centerX = X*20 + 10;
int centerY = Y*20 + 10;
Ellipse2D ellipse = new Ellipse2D.Double();//类以 double 精度定义椭圆。
ellipse.setFrameFromCenter(centerX, centerY, centerX+8, centerY+8);//
Items.add(ellipse);
}
}
}
///下面的两个私有类的用途是定义两个按钮并使其实现清屏(重画)和推出功能。参考书177页
private class ButtonPanel extends JPanel {
public ButtonPanel() {
JButton reset = new JButton("Reset");
add(reset);
JButton quit = new JButton("Quit");
add(quit);
ResetEvent listenerR = new ResetEvent();
reset.addMouseListener(listenerR);//对button reset监听
QuitEvent listenerQ = new QuitEvent();
quit.addMouseListener(listenerQ);
}

private class QuitEvent extends MouseAdapter {
public void mouseClicked(MouseEvent event) {
System.exit(1);
}
}

private class ResetEvent extends MouseAdapter {
public void mouseClicked(MouseEvent event) {
Items.clear();
myRepaint();
}
}
}
private class ButtonPanel2 extends JPanel {
public ButtonPanel2() {
JLabel label=new JLabel("请输入主机IP:");
add(label);
JTextField text=new JTextField("",10);
add(text);
JButton connect =new JButton("connect");
add(connect);
}
}
}

class GameFrame extends JFrame {
public GameFrame() {
setTitle("A Little Game");
setVisible(true);
setSize(400, 500);
setResizable(true);//设置此 frame 是否可由用户调整大小。
winandpanduan win = new winandpanduan();//***************初始化类方法:winandpanduan********
PaintPanel panel = new PaintPanel();
getContentPane().add(panel);
}
}
public class Game {
public static void main(String[] args) {
GameFrame frame = new GameFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

}
}

winandpanduan.java

class winandpanduan
{
private int a[][]=new int[17][17];//初始化 其中a[i][j]的值 0表示没有棋,1表示黑棋,2表示白棋
public winandpanduan()
{
for (int i=0 ;i<17 ;i++ ) {
for (int j=0 ;j<17 ;j++ ) {
a[i][j]=0;
}
}
}

public boolean setpointblack(int x,int y)//设置黑棋
{
a[x][y]=1;
return checkwin(x,y,1);//同时判断是不是有五子连珠出现(黑棋)
}

public boolean setpointwrite(int x,int y)//设置白棋
{
a[x][y]=2;
return checkwin(x,y,2);//同时判断是不是有五子连珠出现(白棋)
}

public boolean checkpoint(int x,int y)
{
if (a[x][y]==1 || a[x][y]==2) {
return false;
}
else
return true;
}

public boolean checkwin(int x,int y,int z)
{ //给一个点,在此点分析是否游戏是否有人胜利
/* 看了一下QQ上面五子棋,直到有五子连珠才给出谁胜
* 俺也这么做
* 开始分析,先只考虑实现,不考虑效益,然后再对算法进行优化
* =====================================================
* 对于一个位置(x,y),下一个连着的棋可以有八个方向
* 2 3 4

* 1 (x,y) 5

* 8 7 6

*
* 最左上角为(0,0)坐标
* 现在只分析如果都有棋子谁胜,而没有分开是白还是黑胜
*/

int times=1; //计数器,记录已经有多少个连着的棋,当times是5时代码return true
int next=1; //开始查找的方向为8时return flase
int temX=x;
int temY=y;
int temZ=z;
//while
//检查15方向
while(true){
if(checkNext(temX-1,temY,1,z)==true){ //1表示1的方向
times++;
temX=temX-1;
continue;//相当是递归的查找1方向
}
else{
break;//1方向没有同颜色的棋
}
}
temX=x+1;
while(true){ //5方向(1的反方向)
if(checkNext(temX,y,5,z)==true){
times++;
temX=temX+1;
continue;
}
else{
break;
}
}

if(times>=5) return true;//五子连珠就返回真


////////////////////////////////////end of check 15 //////////////////////

////////////////////////////////////检查26方向////////////////////////////
times=1;
temX=x-1;
temY=y-1;
while(true){ //检查2方向
if(checkNext(temX,temY,2,z)==true){
times++;
temX-=1;
temY-=1;
continue;
}
else
{
break;
}
}
temX=x+1;
temY=y+1;
while(true){ //检查6方向
if(checkNext(temX,temY,6,z)){
times++;
temX=temX+1;
temY=temY+1;
continue;
}
else
{
break;
}
}
if(times>=5)return true;
////////////////////////////////////////end o check 26/////////////////////////

////////////////////////////////检查37方向/////////////////////////////////////
temX=x;
temY=y-1;
times=1;
while(true){ //看3方向
if(checkNext(temX,temY,3,z)==true){
times++;
temY-=1;
continue;
}
else
{
break;
}
}
temY=temY+1;
while(true){ //看6方向
if(checkNext(temX,temY,7,z)==true){
times++;
temY+=1;
continue;
}
else
{
break;
}
}

if(times>=5)return true;
/////////////////////////////////end of check 5//////////////////////////////

////////////////////////看4 8方向////////////////////////////////////////
temX=x+1;
temY=y-1;
times=1;
while(true){ //看4方向
if(checkNext(temX,temY,4,z)==true){
times++;
temX=temX+1;
temY=temY-1;
continue;
}
else
{
break;
}
}
temX=x-1;
temY=y+1;
while(true){ //看8方向
if(checkNext(temX,temY,8,z)==true){
times++;
temX=temX-1;
temY=temY+1;
continue;
}
else
{
break;
}
}

if(times>=5)return true;

////////////////////////////////end of check 4 8 /////////////////////////
/////////全部完成////////////////////////////////////

return false;//当棋放下时并没有五子连珠
}
private boolean checkNext(int x,int y,int next,int z){ //next表方向,检查下一个方向是否有棋子
switch(next)
{
case 1:

if(x<0) return false;
if(a[x][y]!=0 && a[x][y]==z)
return true;
else
return false;
case 2:

if(x<0||y<0)return false;
if(a[x][y]!=0 && a[x][y]==z)
return true;
else
return false;
case 3:

if(y<0)return false;
if(a[x][y]!=0 && a[x][y]==z)
return true;
else
return false;
case 4:

if(x>16||y<0)return false;
if(a[x][y]!=0 && a[x][y]==z)
return true;
else
return false;
case 5:

if(x>16)return false;
if(a[x][y]!=0 && a[x][y]==z)
return true;
else
return false;
case 6:

if(x>16||y>=16) return false;
if(a[x][y]!=0)
return true;
else
return false;
case 7:

if(y>16)return false;
if(a[x][y]!=0 && a[x][y]==z)
return true;
else
return false;
case 8:

if(x<0||y>16)return false;
if(a[x][y]!=0 && a[x][y]==z)
return true;
else
return false;
default:
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;
}

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;
}
方法二:我自己写的,可以判断
public static boolean panduan(char[][] arr2,int x,int y) //判断是否是五子连珠---------
{
int i,j,k1,k2,a1,a2,a3,a4;
i=y;j=y;
for(;i>=0;){if(arr2[x][i]=='●'){i--;continue;} break;} //横向
for(;j<arr2[x].length;){if(arr2[x][j]=='●'){j++;continue;} break;}
a1=j-i-1;


i=x;j=x;
for(;i>=0;){if(arr2[i][y]=='●'){i--;continue;} break;}//纵向
for(;j<arr2.length;){if(arr2[j][y]=='●'){j++;continue;}break;}
a2=j-i-1;

i=y;j=y; k1=x;
for(;i>=0&&x>=0;){if(arr2[x][i]=='●'){i--;x--;continue;}break;}//左上右下方向
x=k1;
for(;x<arr2.length&&j<arr2[x].length;){if(arr2[x][j]=='●'){j++;x++;continue;}break;}
x=k1;
a3=j-i-1;

i=x;j=x;k2=y; //右上左下方向
for(;i>=0&&y<arr2[i].length;){if(arr2[i][y]=='●'){i--;y++;continue;}break;}
y=k2;
for(;j<arr2[x].length&&y>=0;){if(arr2[j][y]=='●'){j++;y--;continue;}break;}
y=k2;
a4=j-i-1;
if(a1>4||a2>4||a3>4||a4>4)
return true;
return false;
}


----------------解决方案--------------------------------------------------------
  相关解决方案