扎金花這種小遊戲,我想做爲一名程序員。大部分小時候都玩過吧!如今咱們一塊兒來看看搜狐這道面試題吧!看看如何用代碼實現扎金花。java
兩個搜狐的程序員加了一個月班,終於放假了,因而他們決定扎金花渡過愉快的假期 。
共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
(1)拿到玩家1和2輸入的字符串,判斷是否合法code
(2)合法後,拆分字符串爲字符串數組排序
(3)將字符串數組轉化爲int數組,並排序遊戲
(4)判斷3張牌的相等狀況圖片
(5)比較大小,誰輸誰贏字符串
存在10時,字符串的拆分問題:能夠根據字符串長度來判斷拆分
將字母轉爲數字:先將拿到的字符串都轉爲大寫,這樣小寫和大寫字母都同樣了,而後直接用if判斷return就能夠了
比較誰輸誰贏:採用從大到小的方式比較,先判斷是否有豹子,在判斷順子,再判斷對子,最後判斷無牌型的
對順子的處理問題
package 搜狐面試2016; import java.util.Arrays; import java.util.Scanner; public class Test1 { public static void main(String[] args) { // 2,3,4,5,6,7,8,9,10,J,Q,K,A Scanner scanner = new Scanner(System.in); boolean isContinue=true; while (isContinue) { //1.遊戲規則 System.out.println("遊戲規則:共52張普通牌,牌面爲2,3,4,5,6,7,8,9,10,J,Q,K,A之一,大小遞增,各四張; 每人抓三張牌。兩人比較手中三張牌大小,大的人獲勝。"); System.out.println("對於牌型的規則以下:"); System.out.println("1.三張牌同樣即爲豹子"); System.out.println("2.三張牌相連爲順子(A23不算順子)"); System.out.println("3.有且僅有兩張牌同樣爲對子 豹子>順子>對子>普通牌型 在牌型同樣時,比較牌型數值大小"); System.out.println("誰輸誰贏:1 --表明玩家1贏;0 --表明 平局 ;-1 --表明玩家2贏 ;-2 --表明不合法的輸入"); //2.分別出牌 System.out.println("請玩家1出牌:"); String num1 = scanner.next(); System.out.println("請玩家2出牌:"); String num2 = scanner.next(); //3.判斷是否合法 boolean flag=isValid(num1, num2); if(!flag){ //不合法 System.out.println("-2"); }else { //輸入合法---先拆分字符串---再轉化爲int數組 //4.拆分字符串 String[] nums1=getStrArray(num1); String[] nums2=getStrArray(num2); System.out.println("拆分後的字符串數組A:"+Arrays.toString(nums1)); System.out.println("拆分後的字符串數組B:"+Arrays.toString(nums2)); //5.轉化爲int數組 int[] nums11=strToNumber(nums1); int[] nums22=strToNumber(nums2); System.out.println("轉化爲int後的數組A:"+Arrays.toString(nums11)); System.out.println("轉化爲int後的數組B:"+Arrays.toString(nums22)); //6.得到三張牌的相等狀況 int[] equalNum11=equalNum(nums11); int[] equalNum22=equalNum(nums22); System.out.println("三張牌的相等狀況--數組A:"+Arrays.toString(equalNum11)); System.out.println("三張牌的相等狀況--數組B:"+Arrays.toString(equalNum22)); //7.判斷輸贏 int whoWin=whoWin(equalNum11, nums11, equalNum22, nums22); System.out.println(""+whoWin); } //是否繼續 System.out.println("是否繼續?輸入N或n退出,其餘任意鍵繼續!"); String string = scanner.next(); string=string.toUpperCase(); if("N".equals(string)){ isContinue=false; } } } /*1.判斷輸入的內容是否合法 * 不合法兩種狀況:(1)出現的字符不是2,3,4,5,6,7,8,9,10,J,Q,K,A (2)每種牌只有4張,超過4張則不合法了 *方法說明: *該方法只處理狀況(1),狀況(2)放在判斷輸贏的時候處理,由於第二種狀況涉及牌面轉化後計算的問題*/ public static boolean isValid(String num1, String num2) { String reg = "([2-9JQKA]|10){3}";// 正則匹配,只能出現2,3,4,5,6,7,8,9,10,J,Q,K,A,而且一共只能出現3次 boolean a = num1.matches(reg); boolean b = num2.matches(reg); // 有一方不合法就返回false if (a == false || b == false) { return false; } else { // 都合法 return true; } } // 1.拆分字符串,獲得三個數字 public static String[] getStrArray(String num) { // 字符串的長度和拆分後的數組 int length = num.length(); String[] nums = new String[3]; // 不管輸入的J,Q,K,A是否爲大寫,都改成大寫 num.toUpperCase(); // 字符串不含10時,長度都爲3 if (length == 3) { // nums=num.split("");//使用該方法拆分會多出一個空格位--好比33a-->[,3,3,1] for (int i = 0; i < nums.length; i++) { nums[i] = num.substring(i, i + 1); } } else if (length == 4) { // 字符串含一個10 int index = num.indexOf("1"); // 10在首位:10XX if (index == 0) { nums[0] = "10"; nums[1] = num.substring(2, 3); nums[2] = num.substring(3); } else if (index == 1) { // 10在中位:X10X nums[0] = num.substring(0, 1); nums[1] = "10"; nums[2] = num.substring(3); } else { // 10在末位:XX10 nums[0] = num.substring(0, 1); nums[1] = num.substring(1, 2); nums[2] = "10"; } } else if (length == 5) { // 字符串2個10----1010X 或 10X10 或 X1010 int first = num.indexOf("1");// 第一個10 int second = num.lastIndexOf("1");// 第二個10 int cha = second - first; // 兩個1距離大於2時,說明X在中間 if (cha > 2) { nums[0] = nums[2] = "10"; nums[1] = num.substring(2, 3); } else { // 兩個1距離等於2時,說明兩個10是挨在一塊兒的 if (first == 0) { nums[0] = nums[1] = "10"; nums[2] = num.substring(4); } else { nums[0] = num.substring(0, 1); nums[1] = nums[2] = "10"; } } } else { // 字符串爲3個10 for (int i = 0; i < nums.length; i++) { nums[i] = "10"; } } return nums; } // 2.將字符串數組轉爲int數組 public static int[] strToNumber(String[] nums) { int[] arr = new int[3]; for (int i = 0; i < nums.length; i++) { arr[i] = letterToNumber(nums[i]); } Arrays.sort(arr); return arr; } /* * 3.比較拆分後的三個數字相等狀況,並返回數組--[參數1,參數2] * * 參數1:數字相同的個數; * 參數2:如有相同數字,參數2表示相同的是哪一個數字;-------此時參數2只可能爲2-14中的一個 * 若沒有相同數字--參數2表示是否有順子--有順子爲1,沒順子爲0----此時參數2只多是0或1 * * 例如: * 如有兩個相同,則返回[2,相同的數字]; * 若三個都相同,則返回[3,相同的數字]; * 若三個數字都不一樣,且不是順子,則返回[0,0];如果順子則返回[0,1] */ public static int[] equalNum(int[] nums) { int[] arr = new int[2]; // 判斷相等的個數 if (nums[0] == nums[1] && nums[0] == nums[2]) { // 三個數相等 arr[0] = 3; arr[1] = nums[0]; } else if (nums[0] != nums[1] && nums[0] != nums[2] && nums[1] != nums[2]) { // 三個數均不相等--此時有一個順子的問題要處理 arr[0] = 0; // 由於A23不算順子,因此只能出現2-14間的順子,即234,345,...,121314 // 此時相鄰兩個數差爲1 if (nums[1] - nums[0] == 1 && nums[2] - nums[1] == 1) { // 爲順子 arr[1] = 1; } else { arr[1] = 0; } } else { // 兩個數相等 arr[0] = 2; // 若數組中兩個數差值爲0,說明就是這個數爲對子 if(nums[0]-nums[1]==0){ arr[1]=nums[0]; }else if (nums[0]-nums[2]==0) { arr[1]=nums[0]; }else { arr[1]=nums[2]; } } return arr; } /* * 4.判斷誰輸誰贏 參數說明:a,primaryA--玩家1 b,primaryB--玩家2 * * 參數a,b:判斷數字相等狀況後返回的數組----即方法isEqual()處理後的結果 * 參數primaryA,primaryB:原始數組(備註:轉化爲int後的數組---即方法strToNumber()處理後的結果) * * * 備註:該方法太長,能夠將豹子,順子,對子,普通牌型分別提取爲一個方法 * 那麼須要再建立一個方法用於判斷玩家1和2的牌中出現是豹子,順子,對子,普通牌型中的哪種 * 將返回值作爲if的條件,再分別去調用對應的豹子,順子,對子,普通牌型方法 * * 由於這樣方法太多,筆者就不單獨提出來封裝了 */ public static int whoWin(int[] a, int[] primaryA, int[] b, int[] primaryB) { // 1)判斷是否爲豹子 if (a[0] == 3 && b[0] == 3) { // 都是豹子則比大小 if (a[1] > b[1]) { return 1; } else if (a[1] < b[1]) { return -1; } else { // 玩家1和2豹子相同是不可能的,每種牌只有4張 return -2; } } else if (a[0] == 3 && b[0] != 3) { // 只有玩家1是豹子--處理可能出現5張相同牌的狀況--須要判斷玩家2是否有對子,有,那麼是否與豹子是相同的牌 // 玩家2有對子,而且與玩家1的豹子牌面相同 if (b[0] == 2 && a[1] == b[1]) { return -2; } return 1; } else if (a[0] != 3 && b[0] == 3) { // 只有玩家2是豹子--同理上面 // 玩家1有對子,而且與玩家2的豹子牌面相同 if (a[0] == 2 && a[1] == b[1]) { return -2; } return -1; } else { // 2)都沒豹子,判斷是否爲順子--利用非順子時a[1]和b[1]不可能出現1,只會爲2-14 if (a[1] == 1 && b[1] == 1) { // 都爲順子,則比大小--由於是順子,因此比較第一個數值便可 if (primaryA[0] > primaryB[0]) { return 1; } else if (primaryA[0] < primaryB[0]) { return -1; } else { return 0; } } else if (a[1] == 1 && b[1] != 1) { // 只有玩家1是順子 return 1; } else if (a[1] != 1 && b[1] == 1) { // 只有玩家2是順子 return -1; } else { // 3)都不是順子,判斷是否有對子 if (a[0] == 2 && b[0] == 2) { // 都有對對子,則比大小 if (a[1] > b[1]) { return 1; } else if (a[1] < b[1]) { return -1; } else { // 對子相同,則比較單個的那個數 int thirdA = 0;// 玩家1,單獨的牌 int thirdB = 0;// 玩家2,單獨的牌 for (int i = 0; i < primaryA.length; i++) { if (primaryA[i] != a[1]) { thirdA = primaryA[i]; } if (primaryB[i] != b[1]) { thirdB = primaryB[i]; } } // 比較單個數字 if (thirdA > thirdB) { return 1; } else if (thirdA < thirdB) { return -1; } else { return 0; } } } else if (a[0] == 2 && b[0] != 2) { // 只有玩家1有對子 return 1; } else if (a[0] != 2 && b[0] == 2) { // 只有玩家2有對子 return -1; } else { // 4)都沒豹子,順子,對子,直接比大小 if (primaryA[2] > primaryB[2]) { return 1; } else if (primaryA[2] < primaryB[2]) { return -1; } else { // 最大值相等,比較第二大的 if (primaryA[1] > primaryB[1]) { return 1; } else if (primaryA[1] < primaryB[1]) { return -1; } else { // 最大值和第二大值都相等 if (primaryA[0] > primaryB[0]) { return 1; } else if (primaryA[0] < primaryB[0]) { return -1; } else { return 0; } } } } } } } // 5.將字符轉爲數字----------將非數字的J,Q,K,A轉換爲數字11,12,13,14--並將自己數字的字符串轉爲int類型 public static int letterToNumber(String letter) { if (letter.equals("J")) { return 11; } else if (letter.equals("Q")) { return 12; } else if (letter.equals("K")) { return 13; } else if (letter.equals("A")) { return 14; } return Integer.parseInt(letter); } }
長度不合法
單個牌6出現了5次,不合法
豹子
順子和對子
都是字母,順子和對子
出現10,兩個順子
都無牌型,直接比大小