java制作PVP五子棋游戏

来源:互联网 发布:国泰君安快期交易软件 编辑:程序博客网 时间:2024/04/29 06:41

编写五子棋游戏需要处理的问题:

①、下棋时黑白棋子颜色的交替处理

(定义Color类全局变量color来保存颜色标记,当下完一个棋子时颜色变换)

②、点击棋盘时让棋子落在离点击处最近的交叉点上

(判断点击棋盘上的坐标和棋盘上交叉点的坐标的距离)

③、不能让棋子在同一个交叉点重复下棋

      (创建int类二维数组 chess_flag[][]来记录棋盘上的下棋情况,0表示无棋子,1表示黑棋,2表示白棋。判断交叉点对应数组的标记是否为0来下棋。)

④、判断输赢

(用上述二维数组chess_flag来计算当前棋子的标记向上数和向下数后相同标记棋子数之和如果等于4,则该颜色棋子获胜,这是纵向判断,其他方向相同)

⑤、保存棋盘画面

(通过创建结点类Node来保存下棋时棋子坐标和颜色,然后保存到ArrayList类的list链表中。在下棋界面play_panel中调用paint方法中画出保存在链表中的棋子。每次下棋都调用play_panel.repaint()方法来重绘棋盘。)


小知识点:

① 除了JFrame的界面大小可以用setSize方法,大部分小窗体控件用setPreferredSize(new Dimension(length,width))来确定大小。

② JOptionPane是提示框类,JOptionPane.showMessageDialog(this, "提示内容", "标题", JOptionPane.ERROR_MESSAGE);是弹出消息对话框的方法

总结:

五子棋游戏主要是对java的GUI的了解和使用。

package com.huaxin.Chess;import java.awt.Color;import java.awt.Dimension;import java.awt.FlowLayout;import java.awt.Graphics;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.MouseAdapter;import java.awt.event.MouseEvent;import java.util.ArrayList;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JOptionPane;import javax.swing.JPanel;//创建五子棋类 继承窗口类public class Chess extends JFrame{//创建全局变量String cmd_jbt = new String();//创建按钮的标记JPanel panel_play;//创建下棋面板对象Color color = Color.black;//创建棋子黑白颜色标记int[][] chess_flag = new int[19][19]; //创建棋盘数组存放棋子信息int start_flag = 0;//创建开始标记 判断五子棋是否开始了ArrayList<Node> list = new ArrayList<Node>(); //结点链表//创建坐标存放数组的坐标int location_x =0;int location_y =0;//展示下棋界面的方法public void chessUI(){this.setTitle("五子棋");//创建窗口对象FlowLayout flowlayout = new FlowLayout();//创建流式布局对象this.setLayout(flowlayout);//将窗口设置为流式布局this.setSize(1150,860);//设置窗口大小//创建下棋面板 panel_play = new JPanel(){public void paint(Graphics graphics){super.paint(graphics);//绘制面板for(int i=1;i<=19;i++){graphics.drawLine(40,i*40,760,i*40);}for(int i=1;i<=19;i++){graphics.drawLine(i*40,40,i*40,760);}//绘制黑白结点for(int i=0;i<list.size();i++){Node node = list.get(i);graphics.setColor(node.color);  //设置结点的颜色graphics.fillOval(node.x, node.y, 30, 30);  //绘制结点}}};//设置下棋面板背景和大小panel_play.setBackground(Color.lightGray);panel_play.setPreferredSize(new Dimension(800,800));//创建功能选择面板并设置大小JPanel panel_select = new JPanel();panel_select.setBackground(Color.gray);panel_select.setPreferredSize(new Dimension(280,800));//添加面板到窗体this.add(panel_play);add(panel_select);//创建功能按钮JButton jbt_start = new JButton("开始 / 重开");JButton jbt_PVP = new JButton("人人");JButton jbt_PVC = new JButton("人机");JButton jbt_regret = new JButton("悔棋");JButton jbt_about = new JButton("关于");//添加按钮到功能选择面板panel_select.add(jbt_start);panel_select.add(jbt_PVP);panel_select.add(jbt_PVC);panel_select.add(jbt_regret);panel_select.add(jbt_about);//设置按钮的大小jbt_start.setPreferredSize(new Dimension(200,100));jbt_PVP.setPreferredSize(new Dimension(200,100));jbt_PVC.setPreferredSize(new Dimension(200,100));jbt_regret.setPreferredSize(new Dimension(200,100));jbt_about.setPreferredSize(new Dimension(200,100));//创建鼠标监听事件MouseAdapter mouse_adapter = new MouseAdapter(){public void mouseClicked(MouseEvent e){//鼠标点击时//获取点击的坐标int x = e.getX();int y = e.getY();if(x>=20&&x<=770&&y>=20&&y<=770)//判断点击的位置是否在棋盘{//判断点击的位置在交点的哪个位置并为其创建结点if(x%40<10&&y%40<10)//点击点的右下角CreatNode(x-x%40,y-y%40,x-x%40-15,y-y%40-15+0);if(x%40<10&&y%40>10)//点击点的右上角CreatNode(x-x%40+0,y-y%40+40 ,x-x%40-15 , y-y%40-15+40);if(x%40>10&&y%40<10)//点击点的左下角CreatNode(x-x%40+40,y-y%40 ,x-x%40-15+40 ,y-y%40-15 );if(x%40>10&&y%40>10)//点击点的左上角CreatNode(x-x%40+40,y-y%4+40 ,x-x%40-15+40 , y-y%40-15+40);//判断棋子颜色并在数组中做标记if(color == Color.black)//如果棋子颜色为黑色{chess_flag[location_x][location_y] = 1;//在数组中给相应黑色棋子的位置做标记1count_chesses(location_x,location_y);//计算相连棋子数并判断输赢}if(color == Color.white)//如果棋子颜色为白色{chess_flag[location_x][location_y] = 2;//在数组中给相应白色棋子的位置做标记2count_chesses(location_x,location_y);//计算相连棋子数并判断输赢}}}//建立结点private void CreatNode(int i, int j, int k, int l) {//获取交叉点的坐标相应数组的坐标location_x = (i)/40-1;location_y = (j)/40-1;//System.out.println(chess_flag[location_x][location_y]);if(chess_flag[location_x][location_y] != 0)//判断点击位置在数组中相应的位置有没有棋子{JOptionPane.showMessageDialog(Chess.this, "该位置已有棋子,请在其他位置下棋!", "操作错误", JOptionPane.WARNING_MESSAGE);}else {Node node = new Node(k, l, color);//创建结点对象list.add(node);//添加新建的结点给结点链表panel_play.repaint();//执行重画函数change_color();//改变棋子颜色}}};//创建悔棋动作监听对象ActionListener action_listener = new ActionListener(){public void actionPerformed(ActionEvent e) {if(list.size()>0)//判断棋盘是否已经下棋{if(location_x != 20){list.remove(list.size()-1);//去除链表中最后一个结点panel_play.repaint();//重绘下棋面板chess_flag[location_x][location_y]=0;//最后一个棋子在数组中相应变量设为0change_color();//改变画笔颜色//将二维数组坐标设为尾结点坐标location_x =20;//(list.get(list.size()-1).x)/40-1;location_y =20;//(list.get(list.size()-1).y)/40-1;}else{JOptionPane.showMessageDialog(Chess.this, "对方正在悔棋重下,无法进行悔棋", "提示", JOptionPane.WARNING_MESSAGE);//显示关于五子棋的对话框}}}};//给开始按钮添加动作监听对象jbt_start.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {if(start_flag==0){//判断游戏是否已经开始 0为未开始 1为已经开始了panel_play.addMouseListener(mouse_adapter);//给下棋面板添加鼠标监听对象jbt_regret.addActionListener(action_listener);//给后悔按钮添加动作监听对象start_flag = 1;//开始标记设为1 表示游戏已经开始}Reset();//将下棋面板重置};});//给关于按钮添加动作监听对象jbt_about.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent e) {JOptionPane.showMessageDialog(Chess.this, "作者:王锐锋", "关于五子棋", JOptionPane.WARNING_MESSAGE);//显示关于五子棋的对话框}});this.setDefaultCloseOperation(3);//设置窗口默认关闭操作this.setVisible(true);//设置窗口可视化}public void change_color()//调换棋子颜色的方法{//判断标记并设置棋子颜色if(color == Color.black){//g.setColor(Color.black);color = Color.white;}else if(color == Color.white){////color_flag = 0;color = Color.black;}}public void count_chesses(int x1,int y1)//计算相连棋子数{int count_num = 1;//计算相连棋子数for(int i=x1-1;i>=0;i--)//计算棋子左边多少个同色棋子{if(chess_flag[i][y1]==chess_flag[x1][y1]){count_num++;}elsebreak;}for(int i=x1+1;i<=18;i++)//计算棋子右边边多少个同色棋子{if(chess_flag[i][y1]==chess_flag[x1][y1]){count_num++;}elsebreak;}checkIsWin(count_num);//判断输赢count_num =1;//重新计算相连棋子数for(int i=y1-1;i>=0;i--)//计算棋子上边多少个同色棋子{if(chess_flag[x1][i]==chess_flag[x1][y1]){count_num++;}elsebreak;}for(int i=y1+1;i<=18;i++)//计算棋子下边多少个同色棋子{if(chess_flag[x1][i]==chess_flag[x1][y1]){count_num++;}elsebreak;}checkIsWin(count_num);//判断输赢count_num =1;//重新计算相连棋子数for(int i=x1-1,j=y1-1;i>=0&&j>=0;i--,j--)//计算棋子左上边多少个同色棋子{if(chess_flag[i][j]==chess_flag[x1][y1]){count_num++;}elsebreak;}for(int i=x1+1,j=y1+1;i<=18&&j<=18;i++,j++)//计算棋子右下边多少个同色棋子{if(chess_flag[i][j]==chess_flag[x1][y1]){count_num++;}elsebreak;}checkIsWin(count_num);//判断输赢count_num =1;//重新计算相连棋子数for(int i=x1-1,j=y1+1;i>=0&&j<=18;i--,j++)//计算棋子左下边多少个同色棋子{if(chess_flag[i][j]==chess_flag[x1][y1]){count_num++;}elsebreak;}for(int i=x1+1,j=y1-1;i<=18&&j>=0;i++,j--)//计算棋子右上边多少个同色棋子{if(chess_flag[i][j]==chess_flag[x1][y1]){count_num++;}elsebreak;}checkIsWin(count_num);//判断输赢}private void checkIsWin(int count_num) {//判断是否赢了并重新开始下一局// TODO Auto-generated method stubif(count_num == 5&&color ==Color.black){JOptionPane.showMessageDialog(this, "白棋获胜!!!!!", "游戏结束", JOptionPane.ERROR_MESSAGE);//重置所有信息Reset();JOptionPane.showMessageDialog(this, "重新开始游戏", "游戏结束", JOptionPane.WARNING_MESSAGE);}if(count_num == 5&&color ==Color.white) {JOptionPane.showMessageDialog(this, "黑棋获胜!!!!!", "游戏结束",JOptionPane.ERROR_MESSAGE);//重置所有信息Reset();JOptionPane.showMessageDialog(this, "重新开始游戏", "游戏结束", JOptionPane.WARNING_MESSAGE);}}private void Reset() {//重置下棋板的方法color = Color.black;//初始化棋子颜色为黑色for(int i=0;i<chess_flag.length;i++)//将棋盘数组中每个变量归零{for(int j=0;j<chess_flag[i].length;j++){chess_flag[i][j] = 0;}}list.clear();//清除链表中所有结点//点击对应数组坐标归零location_x =0;location_y =0;panel_play.repaint();//重绘下棋面板}}class Node{//给结点类添加属性(交叉点在下棋面板上的坐标,棋子颜色)publicint x=0;publicint y=0;publicColor color;//结点类的构造函数public Node(int x,int y,Color color) {this.x = x;this.y =y;this.color = color;}}



0 0
原创粉丝点击