Java版五子棋

[b]前不久和Java君写了一个五子棋小游戏,清闲时刻不妨与基友对弈几场,也算是小娱怡情,快哉快哉 :D :D [/b]

我是先实现五子棋的棋盘,当然要用重绘函数(不然又会遇到”棋盘去哪儿啦“问题),接下来就是调用鼠标点击事件来放棋子,当然,棋子要存放在一个二维数组中,来记录每一步。最后就是胜负的判定以及步数的计数~

至于创建一个窗体等等,前面的2048已经有所提及,我们直接往下走。
[b]先通过一个重绘函数来实现棋盘和棋子的绘制:[/b]
@Override
public void paint(Graphics g){
super.paint(g);
this.qipan(g);//画棋盘的方法
this.qizi(g);//画棋子的方法
}

大家都可以看到我们分别调用画棋盘和棋子的方法;
[b]//画棋盘方法[/b]
public void qipan(Graphics g){

int i,j ;
for(i=0;i<11;i++){
Color col1 = new Color(250,0,250);
g.setColor(col1);
g.drawLine(50+50*i,100,50+50*i,550);
}
for(j=0;j<10;j++){
Color col2 = new Color(250,0,250);
g.setColor(col2);
g.drawLine(50, 100+50*j, 550, 100+50*j);
}
}
对,这是一个10*11的棋盘,这里一看是用了两个for循环,明显太冗余

完全可以写在一起:
for(int i=0,i<11;i++){
for(int j=0;j<10;j++){
Color col1 = new Color(250,0,250);
g.setColor(col1);
g.drawLine(50+50*i,100,50+50*i,550);
g.drawLine(50, 100+50*j, 550, 100+50*j);
}
}
[b]然后就是画棋子的方法:[/b]//画棋子方法
public void qizi(Graphics g){
for(c=0;c<10;c++){
for(r=0;r<11;r++){
if(array[c][r]==-1){//数组该位置的值
g.setColor(Color.black);
g.fillOval(50*c+25, 50*r+75, 46, 46);
}
else if(array[c][r]==1){
g.setColor(Color.white);
g.fillOval(50*c+25, 50*r+75, 46, 46);
}
}
}
}

[b]这里通过判断数组里的值来判断要绘制出白棋还是黑棋,至于白黑棋子的判断:我是先定义一个计数器,然后通过计数器值的奇偶来给数组的相应位置赋值1或-1,我们画棋子时就可以根据该位置存的值来判定画什么颜色的棋子啦。[/b]//判断黑白棋子
if(count%2==0){
if(array[c][r]==0){//数组该位置初值为0
array[c][r] = -1;
count++;//计数器
g.setColor(Color.black);
g.fillOval(x, y, 46, 46);
this.win(c,r);

jf.setText(""+count);
}
else if(count%2==-1&&count%2==1){
JOptionPane.showMessageDialog( null,"这个位置已经被占用啦 !");
}
}
else if(count%2==1){
if(array[c][r]==0){
array[c][r] = 1;
count++;
//Color col2 = new Color(220,220,220);
g.setColor(Color.white);
g.fillOval(x, y, 46, 46);
}
}


[b]然后添加鼠标监听器:[/b]
g = this.getGraphics();
array=new int[13][12];
MouseListener l1 = new Mouse(g,array,jf);
this.addMouseListener(l1);
[b]
通过构造方法传参(画笔,数组,步数)[/b]
public Mouse(Graphics g,int[][] array,JTextField jf) {
this.g = g;
this.array = array;
this.jf = jf;
}

测试一下,可以监听到鼠标事件,我们可以写鼠标点击方法啦!

[b]我们是在下棋,所以我们的棋子必须要精准的落在棋盘的某个位置,我把他定在了网格交叉点,因为我认为这样更美观一点~[/b]

public void mouseReleased(MouseEvent e) {

x= e.getX();
y= e.getY();

this.huahua();

System.out.println("count= "+count);
}

[b]我们可以先通过监听鼠标释放事件来获取我们鼠标点击的位置:[/b]
public void mouseReleased(MouseEvent e) {

x= e.getX();//鼠标释放点的x坐标
y= e.getY();

this.huahua();

System.out.println("count= "+count);//测试监听器可用
}

然后是棋盘外的判定:

//棋盘外处理
if(x>570){
x=555;
}
if(x<30){
x=31;
}

if(y>570){
y=569;
}
if(y<80){
y=81;
}


[b]这样就保证玩家玩耍时不会出现吧棋子放到棋盘外的尴尬[/b] :lol:

[b]然后就是把棋子放到交叉点处:[/b]

//判定位于数组行列
int c = (int)((x-50)/50);
int r = (int)((y-100)/50);
int a = x%50;
int b = y%50;
if(a>25){
c++;
}
if(b>25){
r++;
}
//画在交叉点
x=50*c+25;
y=50*r+75;

good,只要我们先找出鼠标释放点的最近交叉点(的行数和列数),只要把它的坐标赋值为交叉点坐标就ok拉!

到这里,我们就可以得到五子棋的大部分功能啦,可以出玩一下,找找bug,可偏偏基友明明输了,却借口没有明确的输赢提示而死不认输(”你写的游戏都没说我输我怎么会输,哈哈“),好吧,看来他是不见棺材不掉泪得主,那么我们就加上输赢判断来让他绝望吧!

[b]首先我们要考虑到棋盘是网状的,只要一方出现无论是任意一列或一行,抑或任意对角线上五子相连,那么可以认定该方获胜[/b]。

[b]下面是我的输赢判断的方法:[/b]
//检测输赢
public void win(int c,int r){

flag = false;
int andwin = 0;//计数器来记录第几颗相连棋子

//c向左
for(int i=c;i>0;i--){
if( array[i][r]==array[c][r] ){
andwin++;
}
else
break;
}
//c向右
for(int i=c;i<10;i++){
if(array[i][r]==array[c][r]){
andwin++;
}
else
break;
}
if(andwin==6){
if(array[c][r]==-1){
JOptionPane.showMessageDialog( null,"黑方获胜 !");
}
else if(array[c][r]==1){
JOptionPane.showMessageDialog( null,"白方获胜 !");
}

}
else {
andwin=0;
}

//r横竖方向检测
for(int i=r;i>0;i--){
if( array[c][i]==array[c][r] ){
andwin++;
}
else
break;
}
//r向下
for(int i=r;i<11;i++){
if(array[c][i]==array[c][r]){
andwin++;
}
else
break;
}
if(andwin==6){
if(array[c][r]==-1){
JOptionPane.showMessageDialog( null,"黑方获胜 !");
}
else if(array[c][r]==1){
JOptionPane.showMessageDialog( null,"白方获胜 !");
}
}
else {
andwin=0;
}

//左上-右下方向
for(int i=1;i<10;i++)
for(int j=1;j<11;j++)
for(int k=0;k<=3;k++){
if(array[i][j]!=0){
if(array[i][j]!=array[i+k][j+k])
break;
else if(k==3){
if(array[c][r]==1)
JOptionPane.showMessageDialog( null,"白方获胜 !");
else if(array[c][r]==-1)
JOptionPane.showMessageDialog( null,"黑方获胜 !");
}
}
}

//右上-左下方向
for(int i=1;i<10;i++)
for(int j=3;j<11;j++)
for(int k=-1;k<=3;k++){
if(array[i][j]!=0){
if(array[i][j]!=array[i+k][j-k])
break;
else if(k==3){
if(array[c][r]==1)
JOptionPane.showMessageDialog( null,"白方获胜 !");
else if(array[c][r]==-1)
JOptionPane.showMessageDialog( null,"黑方获胜 !");

}

}
}


[b]不难看出,我是在每个方向都依次遍历检索一遍,来检测有没有5子相连。[/b]

[b]好啦,这下无话可说了吧![/b]

[b]至于栋栋君强烈要求的悔棋,我们以后再议 [/b]:lol:
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值