为了刷算法4,需要java基础,所以花了几天把三季电视剧《Java入门》追完了。之前的编程作业都没有写,最后一个大作业想试试,从12点到凌晨5点,终于搞出了初版。结果,一看别人的作业,许多其他功能都考虑了。
编程时,也遇到了许多的BUG。目前感觉最主要搞清对象的数据结构。而且我感觉自己的作业更多的是面向过程,而不是面向对象。我将OOP简单的当做具有复杂数据结构的对象去用了,也不知道怎么能更好的OOP。
PokerType类描述扑克牌的数据类型
- 它的私有成员都是String型的花色color和点数score.
- 为了实例化对象的方便,定义了含参构造器.同时,为了子类继承方便,也显示写了无参构造器.
- 私有成员可以通过get和set方法读写.
- 为了展示的方便,重写了toString方法,使其能直接打印出类似"黑桃3"的效果
/**
* 创建一个扑克牌类,包括4种花色,13种点数,不考虑大小王
*/
package pers.poker;
/**
* @author YinYajun
*
*/
public class PokerType {
private String color;
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return color+score;
}
private String score;
//无参构造器
public PokerType(){}
//含参构造器
public PokerType(String color,String score){
this.color = color;
this.score = score;
}
/**
* @return the color
*/
public String getcolor() {
return color;
}
/**
* @param color the color to set
*/
public void setcolor(String color) {
this.color = color;
}
/**
* @return the score
*/
public String getScore() {
return score;
}
/**
* @param score the score to set
*/
public void setScore(String score) {
this.score = score;
}
}
Player类描述玩家的数据类型
- 它的私有成员是Integer型的id,string型的name和List<PokerType>的hand(手牌).
- 在含参构造器中,为私有成员初始化,其中hand使用ArrayList<PokerType>的实例化
- 私有成员id和name通过get和set方法读写
- 私有成员hand只有get方法,没有set方法.我们修改hand是使用get方法得到List后,使用List的add方法修改
/**
* 创建两名玩家,至少要有ID,姓名,手牌;手牌为PokerType的Set
*/
package pers.poker;
import java.util.ArrayList;
import java.util.List;
/**
* @author YinYajun
*
*/
public class Player {
private Integer id;
private String name;
private List<PokerType> hand;
//无参构造器
//!!!注意无参构造器也要初始化成员变量,没有传入参数的成员变量除外
public Player(){
this.hand = new ArrayList<PokerType>();
}
//含参构造器
public Player(Integer id,String name){
this.id =id;
this.name = name;
this.hand = new ArrayList<PokerType>();
}
/**
* @return the id
*/
public Integer getId() {
return id;
}
/**
* @param id the id to set
*/
public void setId(Integer id) {
this.id = id;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the hand
*/
public List<PokerType> getHand() {
return hand;
}
CardList类:创建一副牌,洗牌
- 私有成员:List<PokerType> cardList
- 方法:
initialCardList()--创建一副牌;
showList()--展示所有牌,直接打印一个List,需要重写元素的toString方法
shuffleList()--洗牌操作,利用Collections.shuffle方法对List洗牌.
getCardList()--cardList的get方法
/**
* 创建的一幅扑克牌,打乱顺序
*/
package pers.poker;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* @author YinYajun
*
*/
public class CardList {
private List<PokerType> cardList;
//构造函数,初始化cardList
public CardList(){
this.cardList = new ArrayList<PokerType>();
}
/**
* 在cardList中存放所有扑克牌
*/
public void initialCardList(){
System.out.println("-----------创建扑克牌-------------");
String[] colorArray={"黑桃","梅花","方块","红心"};
String[] scoreArray={"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
//遍历52张牌,添加到cardList中
for (String color : colorArray) {
for (String score : scoreArray) {
PokerType newCard = new PokerType(color, score);
cardList.add(newCard);
}
}
System.out.println("-----------扑克牌创建成功-------------");
}
/**
* 遍历展示cardList
*/
public void showList(){
//List可以直接被打印出,但cardList中元素是PokerType类型的(不能直接展示)
//重写PokerType的toString方法
System.out.println(cardList);
// for (PokerType card : cardList) {
// System.out.print(card.getcolor()+card.getScore()+" ");
// }
}
/**
* 洗牌,该方法仅负责洗牌,不负责初始化cardList
*/
public void shuffleList(){
//initialCardList();不能用这句,因为这句就是无脑按顺序加52张牌
//利用Collections.shuffle方法洗牌
System.out.println("-----------开始洗牌-------------");
Collections.shuffle(cardList);
System.out.println("-----------洗牌结束-------------");
}
/**
* @return the cardList
*/
public List<PokerType> getCardList() {
return cardList;
}
DealCard类:发牌
- 私有成员:Player型的player1和player2
- 方法:
playerInfo():填写玩家信息,捕获玩家id是否为整数的异常,并处理。
cardDeal():将洗完的牌发两张给两个玩家,添加到玩家手牌中。
/**
* 将洗牌之后的扑克牌集合,从第一张开始,发给两个玩家,按照一人一张的方式,每人发两张
*/
package pers.poker;
import java.util.InputMismatchException;
import java.util.Scanner;
/**
* @author YinYajun
*
*/
public class DealCard {
private Player player1;
private Player player2;
private Scanner input;
//构造函数,初始化两个Player成员
public DealCard(){
this.player1 = new Player();
this.player2 = new Player();
this.input = new Scanner(System.in);
}
/**
* 输入玩家的信息
*/
public void playerInfo(){
System.out.println("-----------创建玩家-------------");
//输入第一位玩家的信息
System.out.println("请输入第一位玩家的ID和姓名:");
//根据输入类型判断是否为Integer,若遇到不匹配异常,提示输入不匹配,继续提示输入
Integer id1;
boolean exceptionCondition1;
do {
try {
System.out.println("输入ID:");
id1 = input.nextInt();
//用exceptionCondition1为0表示:没有遇到异常
exceptionCondition1 = false;
} catch (InputMismatchException e) {
System.out.println("请输入整数类型的ID!");
input.nextLine();
//用exceptionCondition1为1表示:遇到异常
exceptionCondition1 = true;
id1 =null;
}
} while (exceptionCondition1);
System.out.println("输入姓名:");
String name1 = input.next();
//输入第二位玩家的信息
System.out.println("请输入第二位玩家的ID和姓名:");
Integer id2;
boolean exceptionCondition2;
do {
try {
System.out.println("输入ID:");
id2 = input.nextInt();
//用exceptionCondition为0表示:没有遇到异常
exceptionCondition2 = false;
} catch (InputMismatchException e) {
System.out.println("请输入整数类型的ID!");
input.nextLine();
//用exceptionCondition为1表示:遇到异常
exceptionCondition2 = true;
id2 =null;
}
} while (exceptionCondition2);
System.out.println("输入姓名:");
String name2 = input.next();
//将玩家信息添加到Player成员中去
this.player1.setId(id1);
this.player1.setName(name1);
this.player2.setId(id2);
this.player2.setName(name2);
}
/**
* 给每个玩家发洗玩牌后的前两张
*/
public void cardDeal(){
//创建cardList对象,洗牌
CardList card = new CardList();
card.initialCardList();
card.showList();
card.shuffleList();
System.out.println("-----------开始发牌-------------");
for(int i=0;i<2;i++){
//取得Player型的<PokerType>泛型的List型的手牌集合,为其添加两张手牌
//手牌从CardList对象(洗牌)的<PokerType>泛型的List中抽前两张
//从洗完的牌中抽取的牌给第一个玩家
System.out.println("----玩家:"+player1.getName()+"-拿牌");
PokerType c1 = card.getCardList().get(i);
//!!!报错:因为这里player1是Player型的,调用了无参构造器,而在无参构造器中
//我忘了初始化PokerType泛型的手牌序列hand,所以报NullPointerException
player1.getHand().add(c1);
}
for(int i=2;i<4;i++){
System.out.println("----玩家:"+player2.getName()+"-拿牌");
PokerType c2 = card.getCardList().get(i);
player2.getHand().add(c2);
}
System.out.println("-----------发牌结束-------------");
}
/**
* @return the player1
*/
public Player getPlayer1() {
return player1;
}
/**
* @return the player2
*/
public Player getPlayer2() {
return player2;
}
/**
* 展示玩家的手牌
*/
public void showHand(){
System.out.println("玩家各自的手牌为:");
System.out.println(player1.getName()+player1.getHand());
System.out.println(player2.getName()+player2.getHand());
}
CardComparator:
为了比较牌大小的Comparator实现类,点数优先,点数相同考虑花色,花色按:黑桃>红桃>方块>梅花,将点数和花色改用数字表示
/**
* 点数优先,点数相同考虑花色,花色按:黑桃>红桃>方块>梅花
*/
package pers.poker;
import java.util.Comparator;
/**
* @author YinYajun
*
*/
public class CardComparator implements Comparator<PokerType> {
/**
* 转义,点数统一为数字
*/
public int digitalScore(PokerType arg){
// int score = Integer.parseInt(arg.getScore());
//上面的做法报错:因为字母无法转换为数字,应该是用switch排除后执行这句话
int score;
switch(arg.getScore()){
case("A"):score =1;break;
case("J"):score =11;break;
case("Q"):score =12;break;
case("K"):score =13;break;
default:score = Integer.parseInt(arg.getScore());
}
return score;
}
/**
* 花色,量化为数字
*/
public int digitalColor(PokerType arg){
int color;
switch(arg.getcolor()){
case("黑桃"):color =4;break;
case("红心"):color =3;break;
case("方块"):color =2;break;
default:color =1;
}
return color;
}
@Override
public int compare(PokerType arg0, PokerType arg1) {
// TODO Auto-generated method stub
int arg0score = digitalScore(arg0);
int arg1score = digitalScore(arg1);
int arg0color = digitalColor(arg0);
int arg1color = digitalColor(arg1);
if(arg0score>arg1score)
return 1;
else{
if(arg0score<arg1score)
return -1;
else{
//点数相等了,比较花色
if(arg0color>arg1color){
return 1;
}else{
if(arg0color<arg1color)
return -1;
else
return 0;
}
}
}
}
}
GameRule类:判断输赢
- 方法:handMax(List<PokerType>)返回PokerType--根据CardComparator对手牌排序,返回最大的牌
- handCompare(PokerType, PokerType)--将两名玩家手上最大的牌比较,根据CardComparator的compare方法比较
- game():根据结果,判断输赢!
/**
* 比较两名玩家手牌,取手牌中最大的牌进行比较,点数大的赢
* 若点数最大的牌一样,则按花色比较
*/
package pers.poker;
import java.util.List;
/**
* @author YinYajun
*
*/
public class GameRule {
/**
* 根据手牌,用sort方法(根据CardComparator)排序手牌,获得最大牌
*/
public PokerType handMax(List<PokerType> list){
list.sort(new CardComparator());
//这里出错了,怎么能是排序后第一位呢?那是最小的
return list.get(list.size()-1);
}
/**
* 比较最大牌
*/
public int handCompare(PokerType o1,PokerType o2){
int result =new CardComparator().compare(o1, o2);
return result;
}
public void game(){
DealCard dc = new DealCard();
dc.playerInfo();
dc.cardDeal();
System.out.println("-----------开始游戏-------------");
dc.showHand();
System.out.println("-----------玩家状态-------------");
//玩家1的最大手牌,重写过PokerType的toString方法
PokerType max1 = handMax(dc.getPlayer1().getHand());
System.out.println("玩家:"+dc.getPlayer1().getName()+
"-最大手牌为:"+max1);
//玩家2的最大手牌,重写过PokerType的toString方法
PokerType max2 = handMax(dc.getPlayer2().getHand());
System.out.println("玩家:"+dc.getPlayer2().getName()+
"-最大手牌为:"+max2);
int result = handCompare(max1, max2);
switch(result){
//玩家1获胜
case(1): System.out.println("-----------玩家"+
dc.getPlayer1().getName()+"获胜!-------------");break;
//玩家2获胜
case(-1):System.out.println("-----------玩家"+
dc.getPlayer2().getName()+"获胜!-------------");break;
default:System.out.println("-----------平局!-------------");
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
GameRule game = new GameRule();
game.game();
}
}