java五子棋用了什么类 JAVA五子棋代码
今天给各位分享java五子棋用了什么类的知识,其中也会对JAVA五子棋代码进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!
急!!! Java五子棋源代码注释
package org.liky.game.frame;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
public class FiveChessFrame extends JFrame implements MouseListener, Runnable{
//取得屏幕的宽度
int width= Toolkit.getDefaultToolkit().getScreenSize().width;
//取得屏幕的高度
int height= Toolkit.getDefaultToolkit().getScreenSize().height;
//背景图片
BufferedImage bgImage= null;
//保存棋子的坐标
int x= 0;
int y= 0;
//保存之前下过的全部棋子的坐标
//其中数据内容 0:表示这个点并没有棋子, 1:表示这个点是黑子, 2:表示这个点是白子
int[][] allChess= new int[19][19];
//标识当前应该黑棋还是白棋下下一步
boolean isBlack= true;
//标识当前游戏是否可以继续
boolean canPlay= true;
//保存显示的提示信息
String message="黑方先行";
//保存最多拥有多少时间(秒)
int maxTime= 0;
//做倒计时的线程类
Thread t= new Thread(this);
//保存黑方与白方的剩余时间
int blackTime= 0;
int whiteTime= 0;
//保存双方剩余时间的显示信息
String blackMessage="无限制";
String whiteMessage="无限制";
public FiveChessFrame(){
//设置标题
this.setTitle("五子棋");
//设置窗体大小
this.setSize(500, 500);
//设置窗体出现位置
this.setLocation((width- 500)/ 2,(height- 500)/ 2);
//将窗体设置为大小不可改变
this.setResizable(false);
//将窗体的关闭方式设置为默认关闭后程序结束
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//为窗体加入监听器
this.addMouseListener(this);
//将窗体显示出来
this.setVisible(true);
t.start();
t.suspend();
//刷新屏幕,防止开始游戏时出现无法显示的情况.
this.repaint();
String imagePath="";
try{
imagePath= System.getProperty("user.dir")+"/bin/image/background.jpg";
bgImage= ImageIO.read(new File(imagePath.replaceAll("\\\\","/")));
} catch(IOException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void paint(Graphics g){
//双缓冲技术防止屏幕闪烁
BufferedImage bi= new BufferedImage(500, 500,
BufferedImage.TYPE_INT_RGB);
Graphics g2= bi.createGraphics();
g2.setColor(Color.BLACK);
//绘制背景
g2.drawImage(bgImage, 1, 20, this);
//输出标题信息
g2.setFont(new Font("黑体", Font.BOLD, 20));
g2.drawString("游戏信息:"+ message, 130, 60);
//输出时间信息
g2.setFont(new Font("宋体", 0, 14));
g2.drawString("黑方时间:"+ blackMessage, 30, 470);
g2.drawString("白方时间:"+ whiteMessage, 260, 470);
//绘制棋盘
for(int i= 0; i< 19; i++){
g2.drawLine(10, 70+ 20* i, 370, 70+ 20* i);
g2.drawLine(10+ 20* i, 70, 10+ 20* i, 430);
}
//标注点位
g2.fillOval(68, 128, 4, 4);
g2.fillOval(308, 128, 4, 4);
g2.fillOval(308, 368, 4, 4);
g2.fillOval(68, 368, 4, 4);
g2.fillOval(308, 248, 4, 4);
g2.fillOval(188, 128, 4, 4);
g2.fillOval(68, 248, 4, 4);
g2.fillOval(188, 368, 4, 4);
g2.fillOval(188, 248, 4, 4);
/*
*//绘制棋子 x=(x- 10)/ 20* 20+ 10; y=(y- 70)/ 20* 20+ 70;
*//黑子 g.fillOval(x- 7, y- 7, 14, 14);//白子 g.setColor(Color.WHITE);
* g.fillOval(x- 7, y- 7, 14, 14); g.setColor(Color.BLACK);
* g.drawOval(x- 7, y- 7, 14, 14);
*/
//绘制全部棋子
for(int i= 0; i< 19; i++){
for(int j= 0; j< 19; j++){
if(allChess[i][j]== 1){
//黑子
int tempX= i* 20+ 10;
int tempY= j* 20+ 70;
g2.fillOval(tempX- 7, tempY- 7, 14, 14);
}
if(allChess[i][j]== 2){
//白子
int tempX= i* 20+ 10;
int tempY= j* 20+ 70;
g2.setColor(Color.WHITE);
g2.fillOval(tempX- 7, tempY- 7, 14, 14);
g2.setColor(Color.BLACK);
g2.drawOval(tempX- 7, tempY- 7, 14, 14);
}
}
}
g.drawImage(bi, 0, 0, this);
}
public void mouseClicked(MouseEvent e){
// TODO Auto-generated method stub
}
public void mouseEntered(MouseEvent e){
// TODO Auto-generated method stub
}
public void mouseExited(MouseEvent e){
// TODO Auto-generated method stub
}
public void mousePressed(MouseEvent e){
// TODO Auto-generated method stub
/*
* System.out.println("X:"+e.getX()); System.out.println("Y:"+e.getY());
*/
if(canPlay== true){
x= e.getX();
y= e.getY();
if(x>= 10&& x<= 370&& y>= 70&& y<= 430){
x=(x- 10)/ 20;
y=(y- 70)/ 20;
if(allChess[x][y]== 0){
//判断当前要下的是什么颜色的棋子
if(isBlack== true){
allChess[x][y]= 1;
isBlack= false;
message="轮到白方";
} else{
allChess[x][y]= 2;
isBlack= true;
message="轮到黑方";
}
//判断这个棋子是否和其他的棋子连成5连,即判断游戏是否结束
boolean winFlag= this.checkWin();
if(winFlag== true){
JOptionPane.showMessageDialog(this,"游戏结束,"
+(allChess[x][y]== 1?"黑方":"白方")+"获胜!");
canPlay= false;
}
} else{
JOptionPane.showMessageDialog(this,"当前位置已经有棋子,请重新落子!");
}
this.repaint();
}
}
/* System.out.println(e.getX()+"--"+ e.getY());*/
//点击开始游戏按钮
if(e.getX()>= 400&& e.getX()<= 470&& e.getY()>= 70
&& e.getY()<= 100){
int result= JOptionPane.showConfirmDialog(this,"是否重新开始游戏?");
if(result== 0){
//现在重新开始游戏
//重新开始所要做的操作: 1)把棋盘清空,allChess这个数组中全部数据归0.
// 2)将游戏信息:的显示改回到开始位置
// 3)将下一步下棋的改为黑方
for(int i= 0; i< 19; i++){
for(int j= 0; j< 19; j++){
allChess[i][j]= 0;
}
}
//另一种方式 allChess= new int[19][19];
message="黑方先行";
isBlack= true;
blackTime= maxTime;
whiteTime= maxTime;
if(maxTime> 0){
blackMessage= maxTime/ 3600+":"
+(maxTime/ 60- maxTime/ 3600* 60)+":"
+(maxTime- maxTime/ 60* 60);
whiteMessage= maxTime/ 3600+":"
+(maxTime/ 60- maxTime/ 3600* 60)+":"
+(maxTime- maxTime/ 60* 60);
t.resume();
} else{
blackMessage="无限制";
whiteMessage="无限制";
}
this.canPlay= true;
this.repaint();
}
}
//点击游戏设置按钮
if(e.getX()>= 400&& e.getX()<= 470&& e.getY()>= 120
&& e.getY()<= 150){
String input= JOptionPane
.showInputDialog("请输入游戏的最大时间(单位:分钟),如果输入0,表示没有时间限制:");
try{
maxTime= Integer.parseInt(input)* 60;
if(maxTime< 0){
JOptionPane.showMessageDialog(this,"请输入正确信息,不允许输入负数!");
}
if(maxTime== 0){
int result= JOptionPane.showConfirmDialog(this,
"设置完成,是否重新开始游戏?");
if(result== 0){
for(int i= 0; i< 19; i++){
for(int j= 0; j< 19; j++){
allChess[i][j]= 0;
}
}
//另一种方式 allChess= new int[19][19];
message="黑方先行";
isBlack= true;
blackTime= maxTime;
whiteTime= maxTime;
blackMessage="无限制";
whiteMessage="无限制";
this.canPlay= true;
this.repaint();
}
}
if(maxTime> 0){
int result= JOptionPane.showConfirmDialog(this,
"设置完成,是否重新开始游戏?");
if(result== 0){
for(int i= 0; i< 19; i++){
for(int j= 0; j< 19; j++){
allChess[i][j]= 0;
}
}
//另一种方式 allChess= new int[19][19];
message="黑方先行";
isBlack= true;
blackTime= maxTime;
whiteTime= maxTime;
blackMessage= maxTime/ 3600+":"
+(maxTime/ 60- maxTime/ 3600* 60)+":"
+(maxTime- maxTime/ 60* 60);
whiteMessage= maxTime/ 3600+":"
+(maxTime/ 60- maxTime/ 3600* 60)+":"
+(maxTime- maxTime/ 60* 60);
t.resume();
this.canPlay= true;
this.repaint();
}
}
} catch(NumberFormatException e1){
// TODO Auto-generated catch block
JOptionPane.showMessageDialog(this,"请正确输入信息!");
}
}
//点击游戏说明按钮
if(e.getX()>= 400&& e.getX()<= 470&& e.getY()>= 170
&& e.getY()<= 200){
JOptionPane.showMessageDialog(this,
"这个一个五子棋游戏程序,黑白双方轮流下棋,当某一方连到五子时,游戏结束。");
}
//点击认输按钮
if(e.getX()>= 400&& e.getX()<= 470&& e.getY()>= 270
&& e.getY()<= 300){
int result= JOptionPane.showConfirmDialog(this,"是否确认认输?");
if(result== 0){
if(isBlack){
JOptionPane.showMessageDialog(this,"黑方已经认输,游戏结束!");
} else{
JOptionPane.showMessageDialog(this,"白方已经认输,游戏结束!");
}
canPlay= false;
}
}
//点击关于按钮
if(e.getX()>= 400&& e.getX()<= 470&& e.getY()>= 320
&& e.getY()<= 350){
JOptionPane.showMessageDialog(this,
"本游戏由MLDN制作,有相关问题可以访问www.mldn.cn");
}
//点击退出按钮
if(e.getX()>= 400&& e.getX()<= 470&& e.getY()>= 370
&& e.getY()<= 400){
JOptionPane.showMessageDialog(this,"游戏结束");
System.exit(0);
}
}
public void mouseReleased(MouseEvent e){
// TODO Auto-generated method stub
}
private boolean checkWin(){
boolean flag= false;
//保存共有相同颜色多少棋子相连
int count= 1;
//判断横向是否有5个棋子相连,特点纵坐标是相同,即allChess[x][y]中y值是相同
int color= allChess[x][y];
/*
* if(color== allChess[x+1][y]){ count++; if(color==
* allChess[x+2][y]){ count++; if(color== allChess[x+3][y]){
* count++;}}}
*/
//通过循环来做棋子相连的判断
/*
* int i= 1; while(color== allChess[x+ i][y+ 0]){ count++; i++;}
* i= 1; while(color== allChess[x- i][y- 0]){ count++; i++;} if
*(count>= 5){ flag= true;}//纵向的判断 int i2= 1; int count2= 1;
* while(color== allChess[x+ 0][y+ i2]){ count2++; i2++;} i2= 1;
* while(color== allChess[x- 0][y- i2]){ count2++; i2++;} if
*(count2>= 5){ flag= true;}//斜方向的判断(右上+左下) int i3= 1; int
* count3= 1; while(color== allChess[x+ i3][y- i3]){ count3++;
* i3++;} i3= 1; while(color== allChess[x- i3][y+ i3]){ count3++;
* i3++;} if(count3>= 5){ flag= true;}//斜方向的判断(右下+左上) int i4=
* 1; int count4= 1; while(color== allChess[x+ i4][y+ i4]){
* count4++; i4++;} i4= 1; while(color== allChess[x- i4][y- i4]){
* count4++; i4++;} if(count4>= 5){ flag= true;}
*/
//判断横向
count= this.checkCount(1, 0, color);
if(count>= 5){
flag= true;
} else{
//判断纵向
count= this.checkCount(0, 1, color);
if(count>= 5){
flag= true;
} else{
//判断右上、左下
count= this.checkCount(1,-1, color);
if(count>= 5){
flag= true;
} else{
//判断右下、左上
count= this.checkCount(1, 1, color);
if(count>= 5){
flag= true;
}
}
}
}
return flag;
}
//判断棋子连接的数量
private int checkCount(int xChange, int yChange, int color){
int count= 1;
int tempX= xChange;
int tempY= yChange;
while(x+ xChange>= 0&& x+ xChange<= 18&& y+ yChange>= 0
&& y+ yChange<= 18
&& color== allChess[x+ xChange][y+ yChange]){
count++;
if(xChange!= 0)
xChange++;
if(yChange!= 0){
if(yChange> 0)
yChange++;
else{
yChange--;
}
}
}
xChange= tempX;
yChange= tempY;
while(x- xChange>= 0&& x- xChange<= 18&& y- yChange>= 0
&& y- yChange<= 18
&& color== allChess[x- xChange][y- yChange]){
count++;
if(xChange!= 0)
xChange++;
if(yChange!= 0){
if(yChange> 0)
yChange++;
else{
yChange--;
}
}
}
return count;
}
public void run(){
// TODO Auto-generated method stub
//判断是否有时间限制
if(maxTime> 0){
while(true){
if(isBlack){
blackTime--;
if(blackTime== 0){
JOptionPane.showMessageDialog(this,"黑方超时,游戏结束!");
}
} else{
whiteTime--;
if(whiteTime== 0){
JOptionPane.showMessageDialog(this,"白方超时,游戏结束!");
}
}
blackMessage= blackTime/ 3600+":"
+(blackTime/ 60- blackTime/ 3600* 60)+":"
+(blackTime- blackTime/ 60* 60);
whiteMessage= whiteTime/ 3600+":"
+(whiteTime/ 60- whiteTime/ 3600* 60)+":"
+(whiteTime- whiteTime/ 60* 60);
this.repaint();
try{
Thread.sleep(1000);
} catch(InterruptedException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(blackTime+"--"+ whiteTime);
}
}
}
}
JAVA五子棋代码
import java.util.Arrays;
public class GoBangGame{
public static final char BLANK='*';
public static final char BLACK='@';
public static final char WHITE='O';
public static final int MAX= 16;
private static final int COUNT= 5;
//棋盘
private char[][] board;
public GoBangGame(){
}
//开始游戏
public void start(){
board= new char[MAX][MAX];
//把二维数组都填充‘*’
for(char[] ary: board){
Arrays.fill(ary, BLANK);
}
}
public char[][] getChessBoard(){
return board;
}
public void addBlack(int x, int y) throws ChessExistException{
//@
//char blank='*';
//System.out.println( x+","+ y+":"+ board[y][x]+","+ BLANK);
if(board[y][x]== BLANK){// x, y位置上必须是空的才可以添棋子
board[y][x]= BLACK;
return;
}
throw new ChessExistException("已经有棋子了!");
}
public void addWhite(int x, int y)
throws ChessExistException{
if(board[y][x]== BLANK){// x, y位置上必须是空的才可以添棋子
board[y][x]= WHITE;
return;
}
throw new ChessExistException("已经有棋子了!");
}
//chess棋子:'@'/'O'
public boolean winOnY(char chess, int x, int y){
//先找到y方向第一个不是 blank的棋子
int top= y;
while(true){
if(y==0|| board[y-1][x]!=chess){
//如果y已经是棋盘的边缘,或者的前一个不是chess
//就不再继续查找了
break;
}
y--;
top= y;
}
//向回统计所有chess的个数,如果是COUNT个就赢了
int count= 0;
y= top;
while(true){
if(y==MAX|| board[y][x]!=chess){
//如果找到头或者下一个子不是chess就不再继续统计了
break;
}
count++;
y++;
}
return count==COUNT;
}
//chess棋子:'@'/'O'
public boolean winOnX(char chess, int x, int y){
//先找到x方向第一个不是 blank的棋子
int top= x;
while(true){
if(x==0|| board[y][x-1]!=chess){
//如果x已经是棋盘的边缘,或者的前一个不是chess
//就不再继续查找了
break;
}
x--;
top= x;
}
//向回统计所有chess的个数,如果是COUNT个就赢了
int count= 0;
x= top;
while(true){
if(x==MAX|| board[y][x]!=chess){
//如果找到头或者下一个子不是chess就不再继续统计了
break;
}
count++;
x++;
}
return count==COUNT;
}
//chess棋子:'@'/'O'
public boolean winOnXY(char chess, int x, int y){
//先找MAX向第一个不是 blank的棋子
int top= y;
int left= x;
while(true){
if(x==0|| y==0|| board[y-1][x-1]!=chess){
//如果x已经是棋盘的边缘,或者的前一个不是chess
//就不再继续查找了
break;
}
x--;
y--;
top= y;
left=x;
}
//向回统计所有chess的个数,如果是COUNT个就赢了
int count= 0;
x= left;
y= top;
while(true){
if(x==MAX|| y==MAX|| board[y][x]!=chess){
//如果找到头或者下一个子不是chess就不再继续统计了
break;
}
count++;
x++;
y++;
}
return count==COUNT;
}
//chess棋子:'@'/'O'
public boolean winOnYX(char chess, int x, int y){
//先找到x方向第一个不是 blank的棋子
int top= y;
int left= x;
while(true){
if(x==MAX-1|| y==0|| board[y-1][x+1]!=chess){
//如果x已经是棋盘的边缘,或者的前一个不是chess
//就不再继续查找了
break;
}
x++;
y--;
top= y;
left=x;
}
//向回统计所有chess的个数,如果是COUNT个就赢了
int count= 0;
x= left;
y= top;
while(true){
if(x==0|| y==MAX|| board[y][x]!=chess){
//如果找到头或者下一个子不是chess就不再继续统计了
break;
}
count++;
x--;
y++;
}
return count==COUNT;
}
public boolean whiteIsWin(int x, int y){
//在任何一个方向上赢了,都算赢
return winOnY(WHITE, x, y)||
winOnX(WHITE, x, y)||
winOnXY(WHITE, x, y)||
winOnYX(WHITE, x, y);
}
public boolean blackIsWin(int x, int y){
return winOnY(BLACK, x, y)||
winOnX(BLACK, x, y)||
winOnXY(BLACK, x, y)||
winOnYX(BLACK, x, y);
}
}
自己看看这个行不行,应该能满足你的要求了
JAVA单机版五子棋怎么写
界面思路:
用按钮数组模拟棋盘。
改变按钮的背景图片标志这个棋盘的格子上是黑棋、白棋、空。同时使用一个二维数组记录棋盘棋子的分布,比如qipan[0][0]=1标示第1行第一列的棋子是黑棋子,乙烯类推。
循环检测是否某行、某列、某斜线上是否已经有五个颜色相同的棋子。
简单的算法就是判断某行、某列、某斜线的妻子数目那个最多。通过2个for循环遍历棋盘。
复杂的算法,你看看下面的参考资料,不过下面这段材料如果看不懂的话,用简单的算法实现了五子棋也是很好的了,^_^
五子棋算法(AI)
任何一种棋类游戏其关键是对当前棋局是否有正确的评分,评分越准确则电脑的AI越高。五子棋游戏也是如此,但在打分之前,我们先扫描
整个棋盘,把每个空位从八个方向上的棋型填入数组gStyle(2, 15, 15, 8, 2),其中第一个下标为1时表示黑棋,为2时表示白棋,第二和第三
个下标表示(x,y),第四个下标表示8个方向,最后一个下标为1时表示棋子数,为2时表示空格数,如:
gStyle(1,2,2,1,1)=3表示与坐标(2,2)在第1个方向上相邻的黑棋棋子数为3
gstyle(1,2,2,1,2)=4表示与坐标(2,2)在第1个方向上的最近的空格数为4
在定义方向时,也应该注意一定的技巧,表示两个相反的方向的数应该差4,在程序中我是这样定义的:
Const DIR_UP= 1
Const DIR_UPRIGHT= 2
Const DIR_RIGHT= 3
Const DIR_RIGHTDOWN= 4
Const DIR_DOWN= 5
Const DIR_DOWNLEFT= 6
Const DIR_LEFT= 7
Const DIR_LEFTUP= 8
这样我们前四个方向可以通过加四得到另一个方向的值。如果你还是不太明白,请看下面的图:
---------
---------
---oo----
-ox*xx---
---------
---------
图中的*点从标为(4,4),(打*的位置是空位),则:
gStyle(2,4,4,1,1)=1在(4,4)点相邻的上方白棋数为1
gStyle(2,4,4,1,2)=2在(4,4)点的上方距上方白棋最近的空格数为2
gStyle(1,4,4,3,1)=2在(4,4)点相邻的右方黑棋数为2
gStyle(1,4,4,3,2)=1在(4,4)点的右方距右方黑棋最近的空格数为3
...
一旦把所有空点的棋型值填完,我们很容易地得出黑棋水平方向上点(4,4)的价值,由一个冲1(我把有界的棋称为冲)和活2(两边无界的
棋称为活)组成的。对于而白棋在垂直方向上点(4,4)的价值是一个活1,而在/方向也是活1所以,只要我们把该点的对于黑棋和白棋的价值算出
来,然后我们就取棋盘上各个空点的这两个值的和的最大一点作为下棋的点。然而,对各种棋型应该取什么值呢?我们可以先作如下假设:
Fn表示先手n个棋子的活棋型,如:F4表示先手活四
Fn'表示先手n个棋子的冲棋型,如:F4'表示先手冲四
Ln表示后手n个棋子的活棋型,如:L3表示后手活三
Ln'表示后手n个棋子的冲棋型,如:L3'表示后手冲三
.
.
.
根据在一行中的棋型分析,得到如下关系:
L1'<=F1'<L2'<=F2'<=L1<F1<L2<F2<L3'<=F3'<L4'<F4'=F4
从这个关系包含了进攻和防守的关系(当然,这个关系是由我定的,你可以自己定义这些关系)。对这些关系再进一步细化,如在一个可下
棋的点,其四个方向上都有活三,也比不上一个冲四,所以我们可以又得到4*F3<L4'这个关系,同样,我们还可以得到其它的关系,如:4*F2<L3、4*L3<F3...,这些的关系由于你的定法和我的定法制可能不一样,这样计算机的AI也就不一样,最后我们把分值最小的L1'值定为1,则我们就得
到了下面各种棋型的分值,由C语言表示为:
F[2][5]={{0,2,5,50,16000},{0,10,30,750,16000}};
L[2][5]={{0,1,5,50,3750},{0,10,30,150,4000}};
F数组表示先手,第一个下标为0时表示冲型,第二个下标表示棋子数,则F2'对应F[0][2]L数组表示后手,第一个下标为0时表示冲型,第二
个下标表示棋子数,则L2对应F[1][2]Ok,棋型的分值关系确定好了以后,我们把每一个可下点的四个方向的棋型值相加(包括先手和后手的分
值),最后选择一个最大值,并把这一点作为计算机要下的点就OK了:)。
如果你还想了解更多这方面的信息,记得收藏关注本站。