题目描述
两个搜狐的程序员加了一个月班,终于放假了,于是他们决定扎金花渡过愉快的假期 。
游戏规则:
共52张普通牌,牌面为2,3,4,5,6,7,8,9,10,J,Q,K,A之一,大小递增,各四张; 每人抓三张牌。两人比较手中三张牌大小,大的人获胜。
对于牌型的规则如下:
1.三张牌一样即为豹子
2.三张牌相连为顺子(A23不算顺子)
3.有且仅有两张牌一样为对子 豹子>顺子>对子>普通牌型 在牌型一样时,比较牌型数值大小(如AAA>KKK,QAK>534,QQ2>10104) 在二人均无特殊牌型时,依次比较三张牌中最大的。大的人获胜,如果最大的牌一样,则比较第二大,以此类推(如37K>89Q) 如二人牌面相同,则为平局。
输入描述:
输入两个字符串代表两个玩家的牌(如”10KQ” “354”),先输入的作为玩家1,后输入的作为玩家2
输出描述:
1 代表 玩家1赢 0 代表 平局 -1 代表 玩家2赢 -2 代表不合法的输入
输入例子:
KQ3 3Q9
10QA 6102
5810 7KK
632 74J
10102 K77
JKJ 926
68K 27A
输出例子:
1
1
-1
-1
1
1
-1
题目完整代码如下:
/*
* 文件名:LadFlower.java
* 描述: LadFlower.java
* 修改人:Administrator
* 修改时间:2018年2月23日
* 修改内容:新增
*/
package lin.test.algorithmProblem;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;/**
* 扎金花.
*
* @author Administrator
*/
public class LadFlower {
/**
* 测试主方法.
*
* @param args
* 参数
*/
public static void main(String[] args) {
String aString = args[0];
String bString = args[1];
System.out.println(new LadFlower().comparisonSize(aString, bString));
}
/**
* 比较双方牌大小.
*
* @param input1
* 玩家1牌
* @param input2
* 玩家2牌
* @return 大小
*/
private int comparisonSize(String input1, String input2) {
char[] inputChar1 = input1.toCharArray();
char[] inputChar2 = input2.toCharArray();
// 判断玩家1入参合法性
int a = checkParameter(inputChar1);
if (a != 0) {
return a;
}
// 判断玩家2入参合法性
int b = checkParameter(inputChar2);
if (b != 0) {
return b;
}
List<String> input1s = setInput(inputChar1); // 将玩家1牌字符转换为字符串集合
List<String> input2s = setInput(inputChar2); // 将玩家2牌字符转换为字符串集合
System.out.println("。。。。。。。。。。。。。。。。。。。。。。");
Map<String, Integer> map1 = charCount(input1s); // 计算玩家1不同牌的个数
Map<String, Integer> map2 = charCount(input2s); // 计算玩家2不同牌的个数
switch (map1.size()) {
// 当玩家1为豹子时
case 1:
switch (map2.size()) {
case 1: // 当双方都为豹子时
String card1 = null;
for (String key : map1.keySet()) {
card1 = key;
break;
}
String card2 = null;
for (String key : map2.keySet()) {
card2 = key;
break;
}
return compareSingleCard(card1, card2); // 都为豹子时,只需比较单张牌大小即可
case 2: // 如果玩家1为豹子,玩家2为对子则玩家1大
return 1;
case 3: // 如果玩家1为豹子,玩家2无论是顺子还是单牌,则玩家1大
return 1;
default:
return -2;
}
// 当玩家1为对子时
case 2:
switch (map2.size()) {
case 1: // 当玩家1为对子,玩家2为豹子时,则玩家2大
return -1;
case 2: // 当双方都为对子时
return compareSub(map1, map2); // 比较对子的大小
case 3:
// 如果玩家2为顺子
if (isShunZi(map2)) {
return -1;
} else { // 否则则为单牌
return 1;
}
default:
return -2;
}
// 当玩家1为顺子,或单牌时
case 3:
switch (map2.size()) {
case 1:
return -1;
case 2:
if (isShunZi(map1)) {
return 1;
} else {
return -1;
}
case 3:
if (isShunZi(map1)) {
if (isShunZi(map2)) {
// 双方都是顺子
return compareShunZi(map1, map2); // 比较顺子大小
} else {
return 1;
}
} else {
if (isShunZi(map2)) {
return -1;
} else {
// 双方都是单牌
return compareSingleCard(map1, map2); // 比较每个牌大小
}
}
default:
return -2;
}
default:
return -2;
}
}
private List<String> setInput(char[] inputChar) {
List<String> inputs = new ArrayList<>();
for (Character character : inputChar) {
if (character == '1') {
inputs.add("10");
} else if (character == '0') {
continue;
} else {
inputs.add(character.toString());
}
}
return inputs;
}
/**
* 将牌字符组装成map.
*
* @param inputs
* 字符集合
* @return Map
*/
private Map<String, Integer> charCount(List<String> inputs) {
Map<String, Integer> map = new HashMap<>();
for (String input : inputs) {
if (map.containsKey(input)) {
map.put(input, map.get(input) + 1);
} else {
map.put(input, 1);
}
}
return map;
}
Character[] chars = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'J', 'Q', 'K', 'A'};
List<Character> characters = Arrays.asList(chars);
/**
* 检查入参是否合法.
*
* @param inputChar
* 字符
* @return 数字
*/
private int checkParameter(char[] inputChar) {
int length = inputChar.length;
if (length < 3 || length > 6) {
return -2;
}
if (inputChar[0] == '0') {
return -2;
}
int count = 0;
for (int i = 0; i < length; i++) {
Character character = inputChar[i];
if (!characters.contains(character)) {
return -2;
}
if (i == length - 1) {
if (character == '1') {
return -2;
}
} else {
if (character == '1') {
if (inputChar[i + 1] == '0') {
count++;
} else {
return -2;
}
}
}
if (character == '0' && inputChar[i - 1] != '1') {
return -2;
}
}
if (count + 3 != length) {
return -2;
}
return 0;
}
/**
* 将牌的大小进行排序.
*
* @param map
* 牌
* @return 排序后的数字
*/
private List<Integer> sortCollection(Map<String, Integer> map) {
Set<String> keys = map.keySet();
List<Integer> intCard = new ArrayList<>();
for (String key : keys) {
intCard.add(getIntVlue(key));
}
Collections.sort(intCard, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1 - o2;
}
});
return intCard;
}
/**
* 比较双方都是单牌时的大小.
*
* @param map1
* 玩家1牌
* @param map2
* 玩家2牌
* @return 大小
*/
private int compareSingleCard(Map<String, Integer> map1, Map<String, Integer> map2) {
List<Integer> intCard1 = sortCollection(map1);
int a0 = intCard1.get(0);
int a1 = intCard1.get(1);
int a = intCard1.get(2);
List<Integer> intCard2 = sortCollection(map2);
int b0 = intCard2.get(0);
int b1 = intCard2.get(1);
int b = intCard2.get(2);
if (a > b) {
return 1;
} else if (a < b) {
return -1;
} else {
if (a1 > b1) {
return 1;
} else if (a1 < b1) {
return -1;
} else {
if (a0 > b0) {
return 1;
} else if (a0 < b0) {
return -1;
} else {
return 0;
}
}
}
}
/**
* 比较双方都为顺子时的大小.
*
* @param map1
* 玩家1牌
* @param map2
* 玩家2牌
* @return 大小
*/
private int compareShunZi(Map<String, Integer> map1, Map<String, Integer> map2) {
List<Integer> intCard1 = sortCollection(map1);
int a = intCard1.get(2);
List<Integer> intCard2 = sortCollection(map2);
int b = intCard2.get(2);
if (a > b) {
return 1;
} else if (a < b) {
return -1;
} else {
return 0;
}
}
/**
* 判断牌是否是顺子.
*
* @param map
* 牌
* @return true 或 false
*/
private boolean isShunZi(Map<String, Integer> map) {
List<Integer> intCard = sortCollection(map);
int a = intCard.get(0);
int b = intCard.get(1);
int c = intCard.get(2);
if (a + 1 == b && b + 1 == c) {
return true;
}
return false;
}
/**
* 比较单个牌的大小.
*
* @param card1
* 牌1
* @param card2
* 牌2
* @return 大小
*/
private int compareSingleCard(String card1, String card2) {
int a = getIntVlue(card1);
int b = getIntVlue(card2);
if (a > b) {
return 1;
} else if (a < b) {
return -1;
} else {
return 0;
}
}
/**
* 将牌转化为数字方便比较大小.
*
* @param card1
* 牌
* @return 数字
*/
private int getIntVlue(String card1) {
int a = 0;
switch (card1) {
case "J":
a = 11;
break;
case "Q":
a = 12;
break;
case "K":
a = 13;
break;
case "A":
a = 14;
break;
default:
try {
a = Integer.valueOf(card1);
} catch (Exception e2) {
return -2;
}
break;
}
return a;
}
/**
* 比较双方都为对子时的大小.
*
* @param map1
* 玩家1 牌
* @param map2
* 玩家2 牌
* @return 大小
*/
private int compareSub(Map<String, Integer> map1, Map<String, Integer> map2) {
String card1 = null;
String card11 = null;
for (Map.Entry<String, Integer> map : map1.entrySet()) {
int b = map.getValue();
if (b == 1) {
card11 = map.getKey();
}
if (b == 2) {
card1 = map.getKey();
}
}
String card2 = null;
String card22 = null;
for (Map.Entry<String, Integer> map : map2.entrySet()) {
int b = map.getValue();
if (b == 1) {
card22 = map.getKey();
}
if (b == 2) {
card2 = map.getKey();
}
}
int c = compareSingleCard(card1, card2); // 比较对子牌
// 如果对子牌相等,则比较剩下的单牌大小
if (c == 0) {
int d = compareSingleCard(card11, card22);
return d;
} else {
return c;
}
}}