Java实践之简单的五子棋
通过我们之前对类对象监听器和图像处理的学习,我们可以尝试做一些简单的小游戏,比如老少皆宜的五子棋。
那么我们如何实现五子棋呢?
设计思路
1、我们要画什么?
首先我们要先画出15乘15的棋盘(五子棋标准),画出黑白两子。这些操作都要求我们实现重绘(在我们改变框架大小或者隐藏页面时棋子和棋盘不会消失)
为了完成重绘因此我们需要创建一个MyFrame类,他继承的是JFrame类,因此重写paint方法,其中调用父类super.paint方法,代码如下,在MyFrame里我们需要一个二维数组,用来保存棋盘上的棋子,二维数组的大小就是15乘15,代码如下:
public class MyFrame extends JFrame{
public int[][] chessarray;
public void paint(Graphics g){
super.paint(g);
//绘制棋盘
for(int i=0;i<15;i++) {
g.setColor(Color.BLACK);
g.drawLine(50, 100+i*50, 14*50+50, 100+i*50);
g.drawLine(50+i*50, 100, 50+i*50, 14*50+100);
}
//绘制棋子
for(int i=0;i<15;i++) {
for(int j=0;j<15;j++) {
if(chessarray[i][j]==1) {
g.setColor(Color.BLACK);
g.fillOval(i*50+50-50/2, j*50+100-50/2, 50,50);
}
if(chessarray[i][j]==2) {
g.setColor(Color.WHITE);
g.fillOval(i*50+50-50/2, j*50+100-50/2, 50,50);
}
}
}
}
}
2、对象数组
将棋盘和重绘完成以后,我们要创建一个棋子类,因为我们要通过一个棋子对象来获取它在二维数组的x和y的值,当然只创建一个对象肯定不行,棋盘最大能容纳225个棋子,所以需要创建一个长度为225的对象数组。棋子类中我们要创建一个构造方法,再定义getx和gety两个方法来获取棋子对象的x和y值。代码如下:
public class Chess {
private int chessX;
private int chessY;
public Chess(int x,int y){
chessX=x;
chessY=y;
}
public int getchessX() {
return chessX;
}
public int getchessY(){
return chessY;
}
}
3、最重要的一步
我们要实现棋盘开始和悔棋两个按钮的操作,以及鼠标点击落子的操作,因此我们需要使用事件监听器和鼠标监听器,而且我们要使用MyFrame类中的paint和repaint方法,所以要创建一个MyFrame对象和画笔对象。为了统计当前下了多少个棋子和悔棋操作,我们需要定义一个index的int变量统计个数。还需要一个变量来统计该黑棋落子还是白棋落子,所以我们定义了变量int s=0,每次让s除以2取余,余数为0则黑棋落子,余数为1则白棋落子,这样就解决了黑白子交替下棋的操作。
public void mouseClicked(MouseEvent e){
int x = e.getX();
int y = e.getY();
//下棋子
if((x-50)%50>50/2) {
chessX=(x-50)/50+1;
}else {
chessX=(x-50)/50;
}
if((y-100)%50>50/2)
{
chessY=(y-100)/50+1;
}else {
chessY=(y-100)/50;
}
Chess ch=new Chess(chessX,chessY);
chess[index++]=ch;
if(chessarray[chessX][chessY]==0) {
//黑色先手,黑棋在数组中值为1,白棋为2
if(s%2==0) {
gr.setColor(Color.BLACK);
gr.fillOval(chessX*50+50-50/2, chessY*50+100-50/2, 50,50);
chessarray[chessX][chessY]=1;
}else {
gr.setColor(Color.WHITE);
gr.fillOval(chessX*50+50-50/2, chessY*50+100-50/2, 50,50);
chessarray[chessX][chessY]=2;
}
s++;
System.out.println(s);
whowin(chessX,chessY);
}
}
那么如何判断输赢呢?
首先我们在二维数组中要设立一个标准,黑棋再二维数组中值为1,白棋值为2,0代表该处无棋子。那么每落一个子,他可能是作为右端点或者左端点,上端点或者下端点,需要一个判断来确定下了这个棋子之后它的各个方向本颜色棋子数量变化如何,代码如下:
public void whowin (int x,int y) {
int countlevel = 0;
int countvertical = 0;
int countleft = 0;
int countright = 0;
//水平 ,落子的右边
for(int i=x+1;i<chessarray.length;i++) {
if(chessarray[x][y]==chessarray[i][y]) {
countlevel++;
}else {
break;
}
}
//水平,落子的左边
for(int i=x;i>0;i--) {
if(chessarray[x][y]==chessarray[i][y]) {
countlevel++;
}else {
break;
}
}
//垂直,落子的下面
for(int i=y+1;i<chessarray[0].length;i++) {
if(chessarray[x][y]==chessarray[x][i]) {
countvertical++;
}else {
break;
}
}
//垂直,落子的上面
for(int i=y;i>0;i--) {
if(chessarray[x][y]==chessarray[x][i]) {
countvertical++;
}else {
break;
}
}
//斜方向,右下
for(int i=x+1,j=y+1;i<chessarray.length&&j<chessarray[0].length;i++,j++) {
if(chessarray[x][y]==chessarray[i][j]) {
countright++;
}else {
break;
}
}
//斜方向,左上
for(int i=x,j=y;i>0&&j>0;i--,j--) {
if(chessarray[x][y]==chessarray[i][j]) {
countright++;
}else {
break;
}
}
//斜方向,右上
for(int i=x+1,j=y-1;i<chessarray.length&&j>0;i++,j--) {
if(chessarray[x][y]==chessarray[i][j]) {
countleft++;
}else {
break;
}
}
//斜方向,左下
for(int i=x,j=y;i>0&&j<chessarray[0].length;i--,j++) {
if(chessarray[x][y]==chessarray[i][j]) {
countleft++;
}else {
break;
}
}
最后进行一个判断
//对于count的判断
if(countlevel>=5||countvertical>=5||countright>=5||countleft>=5)
{
if(chessarray[x][y]==1)
{
javax.swing.JOptionPane.showMessageDialog(null, "黑棋获胜");
}
else if(chessarray[x][y]==2)
{
javax.swing.JOptionPane.showMessageDialog(null, "白棋获胜");
}
chessarray=new int[15][15];
mf.chessarray=chessarray;
mf.paint(gr);
s=0;
}
现在就是大功告成了,附上项目截图: