本次作业属于结对编程项目,由我和李凌用了2天时间共同完成。
开始的时候本打算用c编写,但是由于界面问题让我们十分困扰,所以我们经过一番讨论之后决定用比较熟悉的java语言来完成这个项目。正好我eclipse里装了一个可视化编程工具——windowbulider,这样实现一个较为友好的的游戏界面就十分容易了。
首先我们进行了需求分析,李凌看其他组都是规定游戏人数和次数然后进行一次性的全部输入和输出,我们认为这样的游戏非常无聊!因为我们感觉这个游戏的乐趣其实在于玩家会由上一组结果来预测其他人将输入的数并决定本次要输入多大的数(亲自试过这游戏,最后大家输入的数越来越小。。。),是一个心理博弈类的游戏,所以我们决定设计一个不限人数和次数的黄金点游戏。
然后我们设计游戏界面,作为两个理工科的普通学生,我们尽量精简界面,定义了一个JPasswordField作为玩家的加密输入,定义了两个按钮JButton分别添加了单击事件用作输入本次结果和总成绩,定义了一个JTextArea用来显示结果。
设计完界面后我们进行具体编码操作,首先是显示本次结果部分:定义一个字符串用正则表达式获取玩家输入的数并显示结果,定义一个double类型的数组存输入的数(方便取绝对值),经过计算找出胜利者和失败者,算出他们得分和扣分。
然后是显示总分的部分:李凌之前打算在这里一次计算出总成绩,例如:m个人在玩,1号玩家赢了一次输了2次那么得分为m-2-2分。但是之前的单击事件(显示本次结果)得到的结果没有进行保存,而要达到输出目的必须要把每次结果存放到一个容器里然后在输出,所以我们要在显示本次结果的事件里在写一些代码用来存放本次数据。首先我们想到数组但立刻就被我否决了,因为数组长度是固定的,而游戏人数我们不希望是固定的,就好像一帮人玩游戏,突然有个人走了或者有其他人想加入了,那这游戏就不能玩了?所以数组不满足要求,和数组功能类似的是arraylist,这个可以改变长度,并且把索引位置当作玩家就可以输出该玩家的结果。但我感觉既然是一个人对应了一个分数,那么这种映射关系还是用HashMap来存放比较好,这样一个玩家(key)对应着一个得分(value)。所以我们采用了HashMap,每轮都对里面的内容进行修改。然后在显示总分的事件里只需要打印里面的内容即可。
最终代码如下:
1 import java.awt.EventQueue; 2 3 import javax.swing.JFrame; 4 import javax.swing.JPanel; 5 import javax.swing.JPasswordField; 6 import javax.swing.border.EmptyBorder; 7 import javax.swing.GroupLayout; 8 import javax.swing.GroupLayout.Alignment; 9 import javax.swing.JLabel; 10 import javax.swing.LayoutStyle.ComponentPlacement; 11 import javax.swing.JTextField; 12 import javax.swing.JButton; 13 import javax.swing.JTextArea; 14 import java.awt.event.MouseAdapter; 15 import java.awt.event.MouseEvent; 16 import java.util.HashMap; 17 18 public class dfgsd extends JFrame { 19 20 private JPanel contentPane; 21 private JTextField textField; 22 23 public static void main(String[] args) { 24 EventQueue.invokeLater(new Runnable() { 25 public void run() { 26 try { 27 dfgsd frame = new dfgsd(); 28 frame.setVisible(true); 29 } catch (Exception e) { 30 e.printStackTrace(); 31 } 32 } 33 }); 34 } 35 36 /** 37 * Create the frame. 38 */ 39 public dfgsd() { 40 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 41 setBounds(100, 100, 450, 300); 42 contentPane = new JPanel(); 43 contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); 44 setContentPane(contentPane); 45 46 HashMap<Integer,Double> map=new HashMap<Integer,Double>(); 47 48 textField = new JPasswordField(); 49 textField.setColumns(10); 50 51 JTextArea textArea = new JTextArea(); 52 textArea.setWrapStyleWord(true); 53 54 JLabel lblNewLabel = new JLabel("u8BF7u8F93u5165"); 55 56 JButton btnNewButton = new JButton("u67E5u770Bu672Cu6B21u7ED3u679C"); 57 btnNewButton.addMouseListener(new MouseAdapter() { 58 @Override 59 public void mouseClicked(MouseEvent e) { 60 61 int sum = 0; 62 int length = 0; 63 String result = textField.getText(); 64 String[] a = result.split("\D"); 65 for(int i = 0;i < a.length;i++) { 66 textArea.append(((i+1)+"输入的数为" + a[i])); 67 textArea.append(" "); 68 sum =sum + Integer.parseInt(a[i]); 69 length ++; 70 } 71 double b = sum/(length)*0.618; 72 textArea.append("结果为"+b); 73 textArea.append(" "); 74 75 double[] type = new double[a.length]; 76 int max = 1,min = 1; 77 for(int i = 0;i < a.length;i++) { 78 type[i] = Double.parseDouble(a[i]); 79 } 80 double Min = type[0]; 81 double Max = 0f; 82 83 for(int i = 0;i < a.length;i++) { 84 if(Max < java.lang.Math.abs(type[i]-b)) { 85 Max = java.lang.Math.abs(type[i]-b); 86 max = i + 1; 87 } 88 else 89 if(Min > java.lang.Math.abs(type[i]-b)) { 90 Min = java.lang.Math.abs(type[i]-b); 91 min = i + 1; 92 } 93 } 94 95 textArea.append("获胜者是:"+min+"输入的数为"+type[min-1]+"加"+a.length+"分"); 96 textArea.append(" "); 97 textArea.append("失败者是:"+max+"输入的数为"+type[max-1]+"减2分"); 98 textArea.append(" "); 99 100 boolean contains = map.containsKey(max); 101 if(contains) { 102 map.put(max, (double) (map.get(max) - 2)); 103 }else { 104 map.put(max, (double) - 2); 105 } 106 boolean contains2 = map.containsKey(min); 107 if(contains2) { 108 map.put(min, (double) (a.length)+map.get(min)); 109 }else { 110 map.put(min, (double) a.length); 111 } 112 } 113 }); 114 115 JButton btnNewButton_1 = new JButton("u67E5u770Bu6700u7EC8u5F97u5206"); 116 btnNewButton_1.addMouseListener(new MouseAdapter() { 117 @Override 118 public void mouseClicked(MouseEvent e) { 119 120 for (Integer Key : map.keySet()) 121 { 122 textArea.append( Key + ": " + map.get(Key)); 123 textArea.append(" "); 124 } 125 textArea.append("其他人均为0分,请继续努力"); 126 } 127 }); 128 129 GroupLayout gl_contentPane = new GroupLayout(contentPane); 130 gl_contentPane.setHorizontalGroup( 131 gl_contentPane.createParallelGroup(Alignment.LEADING) 132 .addGroup(gl_contentPane.createSequentialGroup() 133 .addGroup(gl_contentPane.createParallelGroup(Alignment.LEADING) 134 .addGroup(gl_contentPane.createSequentialGroup() 135 .addComponent(lblNewLabel) 136 .addPreferredGap(ComponentPlacement.UNRELATED) 137 .addComponent(textField, GroupLayout.PREFERRED_SIZE, 301, GroupLayout.PREFERRED_SIZE)) 138 .addGroup(gl_contentPane.createSequentialGroup() 139 .addGap(60) 140 .addComponent(btnNewButton) 141 .addGap(37) 142 .addComponent(btnNewButton_1)) 143 .addComponent(textArea, GroupLayout.PREFERRED_SIZE, 382, GroupLayout.PREFERRED_SIZE)) 144 .addContainerGap(42, Short.MAX_VALUE)) 145 ); 146 gl_contentPane.setVerticalGroup( 147 gl_contentPane.createParallelGroup(Alignment.LEADING) 148 .addGroup(gl_contentPane.createSequentialGroup() 149 .addGroup(gl_contentPane.createParallelGroup(Alignment.BASELINE) 150 .addComponent(lblNewLabel) 151 .addComponent(textField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) 152 .addPreferredGap(ComponentPlacement.RELATED) 153 .addGroup(gl_contentPane.createParallelGroup(Alignment.BASELINE) 154 .addComponent(btnNewButton) 155 .addComponent(btnNewButton_1)) 156 .addGap(2) 157 .addComponent(textArea, GroupLayout.DEFAULT_SIZE, 206, Short.MAX_VALUE)) 158 ); 159 contentPane.setLayout(gl_contentPane); 160 } 161 }
运行结果:
我俩合影:
对于本次结对编程,万分感谢我的队友李凌 ,他对本次编程非常认真,对我的意见也能认真聆听并给出建议,同时又具有独立分析的能力。两个人共同做一件事大大缩短了项目所需时间。但我感觉结对编程缺点也很明显,这个项目对我来说一个人最多3天完成,两个人虽然只用了2天缩短了开发时间,但2+2=4,相当于实际上花费了4天。这就好比对程序进行设计时,时间和空间永远不能同时达到最优一样。个人感觉只有在任务紧急或者两个人水平都不是太好都不能独立编程的情况下结对编程才是一种好的选择。
总之很高兴能有这样一次机会让我能接触到结对编程,让我体验了有趣的黄金点游戏。
学海无涯,今后我还有很多的路要走,加油吧!!