面向对象上机实验(solitaire纸牌游戏)一、实验要求和目的单人纸牌游戏,牌桌上有7个堆共28张牌,第一堆1张牌,第二堆2张……第7堆7张,每一堆的第一张牌朝上,其他朝下。牌桌上还有4个suitpiles,一个deckcard堆和一个discardcard堆,布局参考windows的纸牌游戏。设计一个简单的CardGames程序,运用面向对象封装、继承、抽象类、抽象方法、多态、动态绑定等概念。二、开发环境硬件环境:win7软件环境:eclipseVersion:LunaRelease(4.4.0)三、小组成员及分工四、实验分析1.此程序需要完成要求:牌桌上有7个堆共28张牌,第一堆1张牌,第二堆2张……第7堆7张,每一堆的第一张牌朝上,其他朝下。同时牌桌上还有4个suitpiles,一个deckcard堆和一个discardcard堆来放置纸牌。通过鼠标的点击和拖动等操作,实现游戏的进行。2.任务定义:(1)如何存储和定义52张牌,所选择的储存结构需要便于实现实验给出的题目要求。(2)如何设计鼠标操作程序,实现纸牌的拖动和放置,实现只有当纸牌拖动到合适的位置才可放置。(3)如何设计翻牌程序,包括点击DiscardPile堆中的纸牌的翻牌,以及桌面纸牌当移走最上方的纸牌后的自动翻牌。(4)如何设置纸牌的初始化:实现随机配牌。3.原始数据的输入:由于在程序中引入随机数生成器随机配牌,因此程序不需要任何形式的输入,只需用户选择执行或不执行此程序,程序执行后,用户进行相应的操作执行游戏。五、实验内容1.主要技术这次的设计主要囊括了面向对象中的封装,多态,继承中的特化子类化等概念。2.主要思路先定义纸牌拥有的包括大小花色数值和图片的属性,接着创建牌堆类,有5种牌堆,先编写一个总牌堆CardPile,定义好其属性,然后通过对基类CardPile的继承和改写实现其他的几个牌堆。牌堆的方法有判空,得到top的纸牌,弹出纸牌,以及接受纸牌,是否能接受纸牌等等的方法。其中discardpile类增加一个加牌的方法,suitpile类中添加了判断纸牌是否能放入的方法,tablepile类的实现重写了总牌堆的某些方法,加了是否选中纸牌的方法。得到纸牌的花色,点数以及各类其他属性的方法。同时还定义了一个暂存移动的牌的牌堆(movecardpile)的类,多了一个size(),和移除增加牌的方法。3.主要代码Card.java:定义了牌堆的基本特性和操作,作为基类,便于后面各类牌堆的继承使用。publicclassCardPile{protectedintx;protectedinty;publicStackCardthePile;publicCardPile(intxl,intyl){x=xl;y=yl;thePile=newStackCard();//将牌堆的数据结构定义为堆栈}publicCardtop(){//显示最上层,否则返回空if(!(thePile.empty()))return(Card)thePile.peek();elsereturnnull;}publicbooleanisEmpty(){//判断牌堆是否为空returnthePile.empty();}publicCardpop(){try{return(Card)thePile.pop();//将堆栈中的第一张牌弹出}catch(EmptyStackExceptione){returnnull;}}publicbooleanincludes(inttx,intty){//通过牌的坐标和宽高判断是否在区域内部returnthis.x=tx&&tx=this.x+Card.width&&this.y=ty&&ty=this.y+Card.height;}publicintselect(inttx,intty){//select执行响应鼠标单击的行为if(includes(tx,ty)){if(isEmpty())return-2;elsereturnthePile.size()-1;}elsereturn-1;}//同名多方法调用publicvoidaddCard(Objectcard){Cardcards;if(cardinstanceofArrayList?){for(intn=0;n((ArrayListCard)card).size();n++)thePile.push(((ArrayListCard)card).get(n));}else{cards=(Card)card;thePile.push(cards);}}publicvoidremoveCard(Collection?card){thePile.removeAll(card);}publicbooleanisCanAdd(Cardcard){returnfalse;}publicvoiddisplay(Graphicsg){//显示整副牌堆if(isEmpty()){Imageimage=null;try{Stringpicture=picture/0.png;image=ImageIO.read(newFile(picture));}catch(IOExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();System.out.println(class-CardPile-display-if(isEmpty()));}g.drawImage(image,this.x,this.y,Card.width,Card.height,null);}else{top().setX(x);top().setY(y);top().draw(g);}}}DiscardPile.java:通过对CardPile的继承并改写,实现单击左上角的牌叠来拖动更多纸牌。publicclassDiscardPileextendsCardPile{publicDiscardPile(intx,inty){super(x,y);//调用父类的构造方法}publicvoidaddCard(Objectcard){Cardcards;if(cardinstanceofArrayList?){cards=((ArrayListCard)card).get(0);}elsecards=(Card)card;if(!(cards.isFaceup()))cards.setFaceup(true);thePile.push(cards);}}DeckPile.java:直接继承自Cardpile类,为旁边牌堆获取的纸牌提供一个放置的牌堆。publicclassDeckPileextendsCardPile{publicDeckPile(intx,inty){super(x,y);}}4.实验结果纸牌游戏的主界面游戏结束的界面六、结论分析与体会通过这个学期的对面向对象的学习和实验,让我对面向对象有了更加深入的了解,通过对继承多态等方法的运用,实现了代码重写,认识到了对提高软件开发效率的重大作用。在实验中,我们理解理论课上的知识,然后运用到实际的操作中,我们必须在现有的理论的基础上,进行实践。多次实验后,也让我看到了现在学习的一个很大弱点:只听不练,永远不会熟练运用;空记技巧,忽略思想,会在多变的习题中十分无奈。