java学习-质数的孤独
正在看质数的孤独,,,于是写了一个练习代码,输出1-100之间的质数
代码比较烂。待完善吧。
这里用到了continue和break,continue指结束当前轮次循环,跳入下一个循环,break指结束当前循环,进入下一步。
在网上找了别人的代码做参考,优化如下:
上面的代码不正确,只能到3 5 7,需要改成下面的代码:
原因是,flag定义在循环体外面,所以一旦从true改成false之后,状态是不能回去的,就一直false了,后面那句话永远不能输出。
定义一个接口,使用匿名内部类方式创建接口的实例
public interface Oil{ String color="yellow"; public String use(); public String msg(String tool); } public class Pen { public void test(Oil o,String tool){ System.out.println(o.use()); System.out.println(o.msg(tool)); } public static void main(String[]args){ Pen p=new Pen(); String tool="The tool is Pen"; p.test( new Oil(){ public String use(){ return "It is for write"; } public String msg(String tool){ return tool+",the color is "+color; } },tool); } }
java - 练习,定义一个抽象类,通过抽象的类来派生子类
public abstract class Car{ { System.out.println("init car"); } private String color; //public abstract String Certificate(); public abstract String getType(); public Car(){} public Car(String color){ System.out.println("exe car"); this.color=color;//without this ,the color couldn't send to the car Object } public void setColor(String color) { this.color = color; } public String getColor() { return this.color; } } public class Tractor extends Car{ private int paWeight;//weight of passenger private int toolWeight;//weight of tool public void setWeight(int paWeight,int toolWeight){ if(paWeight<=0||toolWeight<=0){ System.out.println("the weight of passenger and tools can't be less than 0"); } this.paWeight=paWeight; this.toolWeight=toolWeight; } public Tractor(String color,int paWeight,int toolWeight){ super(color); this.setWeight(paWeight,toolWeight); } public String getType(){ return "the paWeight is :"+paWeight+",the toolWeight is :"+toolWeight+"; the color is "+getColor(); }; public static void main(String[]args){ Car c1=new Tractor("yellow",2,300); System.out.println(c1.getType()); } }
java -练习 给定半径 圆大小随之变化
参考:https://www.cnblogs.com/TaoLeonis/p/6507052.html
画圆代码
public static void paint(int r){ for(int i = r;i>=r*(-1);i--){ int a=r-(int)Math.sqrt((r*r)-(i*i)); //*左侧的间隔数 int b=r-a;//两个*之间的间隔数 String str=space(a)+"*"+space(b*2)+"*"; System.out.println(str); } } public static String space(int x){ String str = ""; for(int i=0;i<x;i++){ str = str+"--"; } return str; } public static void main(String []args){ //int r = getInput(); //paint(r); paint(6); }
原理:
输入数字代码
public static int getInput(){ int a =-1; while(true){ Scanner scan = new Scanner(System.in); if(scan.hasNextInt()){ a=scan.nextInt(); if (a>0){ System.out.println("输入的数据为:" + a); break;} else{ System.out.println("请重新输入"); } }else{ System.out.println("请重新输入"); } } return a ; }
按字节来截取字符串子串
public class SubStringTest { public static void main(String[]args){ String str="中国国国abcb"; System.out.println(str.substring(1, 8)); System.out.println(test(str,1,8)); } public static String test(String str ,int a,int b){ for(int i=a;i<b;i++){ if(str.charAt(i)<0||str.charAt(i)>127){ b=b-1; } } return str.substring(a,b); } }
输出结果
国国国abcb gggggab 国国国a
把数字转化为钱币
写到最后懒得写小数部分了,反正逻辑都是一样绕。
package chapter4; public class FloatToRmb { public static void main(String[] args) { double f = 1006.789; String[] ds = num(f); String begin = ds[0]; String after = ds[1]; String str = ""; if (begin.length() > 0) str = handleBefore(begin); if (after.length() > 0) { str = str + handleAfter(after); } System.out.println(str); } public static String handleBefore(String str) {// 1006 String str1 = ""; if (str.length() > 0) {// 2{ if (!str.substring(str.length() - 1).equals("0"))// 6 str1 = str.substring(str.length() - 1) + "元"; str = str.substring(0, str.length() - 1); System.out.println(str.length()); } if (str.length() > 0) {// 2 if (!str.substring(str.length() - 1).equals("0"))// 6 { str1 = str.substring(str.length() - 1) + "shi" + str1; } else { str1 = "零" + str1; } str = str.substring(0, str.length() - 1); } if (str.length() > 0) {// 2 if (!str.substring(str.length() - 1).equals("0"))// 6 { str1 = str.substring(str.length() - 1) + "bai" + str1; } else if (!str1.startsWith("零")) { str1 = "零" + str1; } str = str.substring(0, str.length() - 1); } if (str.length() > 0) {// 2 if (!str.substring(str.length() - 1).equals("0"))// 6 str1 = str.substring(str.length() - 1) + "qian" + str1; } return str1; } public static String toChineseNum(int a) { String str = ""; switch (a) { case 1: str = "壹"; case 2: str = "贰"; case 3: str = "叁"; case 4: str = "肆"; case 5: str = "伍"; case 6: str = "陆"; case 7: str = "柒"; case 8: str = "捌"; case 9: str = "久"; } return str; } public static String handleAfter(String str) { return "2"; } public static String[] num(double d) { String[] ds = { "", "" }; String str = String.valueOf(d); int num = str.indexOf("."); ds[0] = str.substring(0, num); ds[1] = str.substring(num + 1); return ds; } }
改进版
思路想好了
对所有数值,都转换成 xxxxxxx的格式
即 1006 转为 1006000,10067转为1006700 ,6.7转为0006700;
对任意7位数,插入字符
String 1 ="1234567";
String 2 = "千百十元角分毫"
str="1千2百3十4元5分6角7毫";
package chapter4; public class FloatToRmb { public static void main(String[] args) { double d=10.078; int a=(int)(d*1000);//1066789 String str=String.valueOf(a); if(str.length()<=1){ str="零"; } while(str.length()!=7){ str="0"+str; } String str1="千百十元角分毫";//3 String str2=""; for(int i=str.length();i>0;i--){ if(!str.substring(i-1,i).equals("0")){ str2=str.substring(i-1,i)+str1.substring(i-1, i)+str2; }else if (str.substring(i-1,i).equals("0") &&(!str2.startsWith("零")) &&((i-1)<3) &&(!str.startsWith("0")) &&!str2.startsWith("元")//元 ){//indexof 似乎不能识别中文? System.out.println(str1.indexOf("元")+","+(i-1)); str2="零"+str2; }else if(!str2.startsWith("元") &&((i-1)==3)){ str2="元"+str2; } System.out.println(str.substring(i-1, i)); str1=str1.substring(0, i-1); str=str.substring(0, i-1); } System.out.println(str2); } }
逻辑判断的部分太垃圾了。。。。还需要改进
改进后的版本:
1.先把位数插入到字符串中
2.再分析语义,字符串中需要做处理的只有 元 和零这两个字。修改代码,在字符串基础上,分别插入元和零这两个字就可以了。
package chapter4; public class FloatToRmb { public static void main(String[] args) { double d=010.078; int a=(int)(d*1000);//1066789 String str=String.valueOf(a); String str2=""; if(str.length()<=1&&str.toString().equals("0")){ str2="零"; }else if(str.length()<=1&&(!str.toString().equals("0"))){ str2=str+"毫"; } while(str.length()!=7){ str="0"+str; } String str1="千百十元角分毫";//3 if(str2.equals("")){ for(int i=str.length();i>0;i--){ if(!str.substring(i-1,i).equals("0")){//给不等于0的位数加上单位 str2=str.substring(i-1,i)+str1.substring(i-1, i)+str2; } else if(str.substring(i-1,i).equals("0")//当前位数为0时 &&((i-1)==3)//整数部分 &¬AllZero(str)){//给个位数为0,但整数部分不全为零的部分 ,加上元单位 str2="元"+str2; System.out.println("当前位数为:"+(i-1)+",整数部分不全为0?:"+notAllZero(str)); } else if((!str2.startsWith("元")) &&(notAllZero(str)) &&str.substring(i-1,i).equals("0") &&(i-1<=3)){//整数部位中,str2不以元开头,整数部分不全为零,当前单位str为0,加上“零” str2="零"+str2; } str=str.substring(0,i-1);//每个循环,缩短一下str的尾部 } } System.out.println(str2); } public static boolean notAllZero(String str){ boolean b = false;//默认全0 while(str.length()>0){ if(!(str.substring(str.length()-1, str.length()).equals("0"))){ b=true; break; } str=str.substring(0,str.length()-1); } return b; } }
其实还是很辣鸡。。。。_(:з)∠)_
看了下,网上的大多数解决办法是把浮点数和整数分开处理,然后用数组来循环。
唔。。。。好吧
改进了一下代码
可以处理4位的亿的数值
package chapter4; public class FloatToRmb { static String []bigDigit={"元","万","亿"}; static String []staticDigit={"零","壹","贰","叁","肆","伍","陆","柒","捌","玖"}; static String zero="零"; public static void main(String[] args) { double l=100000.1; System.out.println(toChinese(getString(l))); } public static String getString(double l){ long a=(long) Math.floor(l); long b=Math.round((l-a)*100); String inte=String.valueOf(a); String floate=String.valueOf(b); String str=""; String[]intee=cutNum(inte); if(!((inte.length()==1)&&inte.equals("0"))){ for(int i=0;i<intee.length;i++){ // System.out.print(intee[i]); str=handleNum(intee[i])+bigDigit[i]+str; } } return str=str+handleFloat(floate); } public static String toChinese(String num){ String result=""; for(int i =0;i<num.length();i++){ //对每一位进行遍历,每一位从0~9,分别赋值staticDigit[0]~[9] if(num.substring(i,i+1).matches("\d")){ int j =Integer.valueOf(num.substring(i,i+1)); result=result+staticDigit[j]; }else{ result=result+num.substring(i,i+1); } } return result; } public static String handleFloat(String num){//11 String a =""; String [] f={"角","分"}; // System.out.println(num.length()); if(num.length()!=0){ for(int i =0;i<num.length();i++){ if(!num.substring(i, i+1).equals("0")){ a=a+num.substring(i,i+1)+f[i]; } } } return a; } public static String[] cutNum(String num){ int digit=getDigit(num.length()); String []a=new String[digit]; while(num.length()<4*digit){ num="0"+num; } for(int i=0;i<digit;i++){ //将num进行四位切割 a[i]=num.substring((digit-i-1)*4,(digit-i)*4);//从后往前填充 } return a; } public static String handleNum(String num){ String []smallDigit={"千","百","拾",""}; String newNum=""; for(int i=num.length();i>0;i--){//1010 i=1 if(!num.substring(i-1,i).equals("0")){//给不等于0的位数加上单位 newNum=num.substring(i-1,i)+smallDigit[i-1]+newNum; } else if( num.substring(i-1,i).equals("0")//当前位的数值为0,后面数值有,前面数值不全为0,补“零" &&(newNum.length()!=0) &&(notAllZero(num)) ){ newNum=zero+newNum; } num=num.substring(0,i-1);//每个循环,缩短一下str的尾部 } return newNum; } public static int getDigit(int length){ int a =0; a=(int)Math.ceil((double)length/4); return a ; } public static boolean notAllZero(String str){ boolean b = false;//默认全0 while(str.length()>0){ if(!(str.substring(str.length()-1, str.length()).equals("0"))){ b=true; break; } str=str.substring(0,str.length()-1); } return b; } }
五子棋
增加gameOver()方法,判断落子之后,棋局是否结束
结束的标准:
1.棋盘已满
2.横,竖,左斜,右斜 5个子相连
第一版本:
对棋盘上的所有的位置进行校验,看看是否结束战斗:
_(:з)∠)_ 好鸡儿烦躁啊,不能用一个循环和一个数组搞定。。。。
package chapter4; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class Gobang { // 定义棋盘的大小 private static int BOARD_SIZE =7; // 定义一个二维数组来充当棋盘 private static int EDGE=4; private String[][] board; private int color=0; public void initBoard(){ board=new String[BOARD_SIZE][BOARD_SIZE]; for(int i =0;i<BOARD_SIZE;i++){//列 //打印x个+ for(int j =0;j<BOARD_SIZE;j++){//行 board[i][j]="+ ";//数组的内容在赋值之前需要先初始化,不然会报nullPoint错误 } } } public void showBoard(){ for(int i =0;i<BOARD_SIZE;i++){//列 //打印x个+ for(int j =0;j<BOARD_SIZE;j++){//行 System.out.print(board[i][j]);//j从0~14打印不换行 } System.out.println();//i 从0~14打印换行 } System.out.println("____________________________________"); } public Boolean paint(int i,int j ){ Boolean flag=false; if(i>BOARD_SIZE||i<1||j>BOARD_SIZE||j<1){ return false; } //怎么判断是写○还是写*? // color=0 下O,为用户方,=1 下第二个,为PC方; if(board[i-1][j-1].equals("+ ")){ if(color==0){ board[i-1][j-1]="○ "; color=1; }else if(color==1){ board[i-1][j-1]="Q "; color=0; } flag=true; } return flag; } public int random(){ return (int)Math.round(Math.random()*(BOARD_SIZE-1)+1); } //flag为true时,游戏结束 public Boolean gameOver(String i){ //1.棋盘占满 横向对比 Boolean flag=false;//游戏未结束 String [][]board_change=new String[BOARD_SIZE][BOARD_SIZE]; int [][]board_judge=new int [BOARD_SIZE][BOARD_SIZE]; int[][] board_judge2=new int [BOARD_SIZE][BOARD_SIZE]; for(int j=0;j<BOARD_SIZE;j++){ String str1=""; int count_x=0; for(int k=0;k<BOARD_SIZE;k++){ board_change[k][j]=board[j][k]; str1=board[j][k]+str1; if(board[j][k].equals(i)){ count_x=count_x+1; if(count_x>=EDGE){ flag=true; System.out.println(i+"胜利了,游戏结束。");//横向对比 return flag; } if(j==0){ board_judge[j][k]=1; System.out.println("j:"+j+",k:"+k+",board_judge[j][k]:"+board_judge[j][k]); } //左斜判断 if((k>0)&&(board_judge[j-1][k-1]==j)){ board_judge[j][k]=j+1; } //右斜判断 if(k<BOARD_SIZE-1&&(board_judge2[j-1][k+1]==j)){ board_judge2[j][k]=j+1; } if(board_judge[j][k]==5||board_judge2[j][k]==5){ flag=true; System.out.println(i+"胜利了,游戏结束。");//对角线对比 } }else if(!board[j][k].equals(i)){ count_x=0; } if((!str1.contains("+ "))&&(j==BOARD_SIZE-1)&&(k==BOARD_SIZE-1)&&(!board[j][k].equals("+ "))){ System.out.println("棋盘已满,和"); flag=true; return flag; } } } //竖着 for(int j=0;j<BOARD_SIZE;j++){ String str1=""; int count_x=0; for(int k=0;k<BOARD_SIZE;k++){ str1=board_change[j][k]+str1; if(board_change[j][k].equals(i)){ count_x=count_x+1; if(count_x>=EDGE){ flag=true; System.out.println(i+"胜利了,游戏结束。");//横向对比 return flag; } }else if(!board_change[j][k].equals(i)){ count_x=0; } if((!str1.contains("+ "))&&(j==BOARD_SIZE-1)&&(k==BOARD_SIZE-1)&&(!board_change[j][k].equals("+ "))){ System.out.println("棋盘已满,和"); flag=true; return flag; } } } return flag; } public static void main(String []args) throws NumberFormatException, IOException{ Gobang gb=new Gobang(); System.out.println("—————————————————五子棋游戏—————————————————"); System.out.println("请输入1~"+BOARD_SIZE+"的数字"); gb.initBoard(); //get输入,用,分离 BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String inputStr = null; // br.readLine():每当在键盘上输入一行内容按回车,用户刚输入的内容将被br读取到。 while ((inputStr = br.readLine()) != null) { // 将用户输入的字符串以逗号(,)作为分隔符,分隔成2个字符串 if(!inputStr.contains(",")){ System.out.println("需要输入英文逗号哦,请重新输入~"); continue; } String[] posStrArr = inputStr.split(","); // 将2个字符串转换成用户下棋的座标 int xPos = Integer.parseInt(posStrArr[0]); int yPos = Integer.parseInt(posStrArr[1]); if(xPos<1||xPos>BOARD_SIZE||yPos<1||yPos>BOARD_SIZE){ System.out.println("请输入1~"+BOARD_SIZE+"的数字"); continue; } if(gb.paint(xPos,yPos)){ gb.showBoard(); }else{ System.out.println("当前位置已有棋子,请重新落子"); continue; } // System.out.println(gb.gameOver(0)); if(gb.gameOver("○ ")){ break; } while(true){ if(gb.paint(gb.random(),gb.random())){ gb.showBoard(); break; }else{ continue; } } if(gb.gameOver("Q ")){ break;} } } }
第二版本:
参考了其他人用GUI写的用例,修改规则:
1.只对落子的位置进行判断,不用对整个棋盘遍历
_(:з)∠)_ 日哦,又要重写一发,我怎么这么笨。
搞定了,只写了横向对比,其他方向的以此类推了,懒得动了。。。。
package chapter4; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class Gobang { // 定义棋盘的大小 private static int BOARD_SIZE =7; // 定义一个二维数组来充当棋盘 private static int EDGE=4; private String[][] board; private int color=0; public void initBoard(){ board=new String[BOARD_SIZE][BOARD_SIZE]; for(int i =0;i<BOARD_SIZE;i++){//列 //打印x个+ for(int j =0;j<BOARD_SIZE;j++){//行 board[i][j]="+ ";//数组的内容在赋值之前需要先初始化,不然会报nullPoint错误 } } } public void showBoard(){ for(int i =0;i<BOARD_SIZE;i++){//列 //打印x个+ for(int j =0;j<BOARD_SIZE;j++){//行 System.out.print(board[i][j]);//j从0~14打印不换行 } System.out.println();//i 从0~14打印换行 } System.out.println("____________________________________"); } public Boolean paint(int i,int j ){ Boolean flag=false; if(i>BOARD_SIZE||i<1||j>BOARD_SIZE||j<1){ return false; } //怎么判断是写○还是写*? // color=0 下O,为用户方,=1 下第二个,为PC方; if(board[i-1][j-1].equals("+ ")){ if(color==0){ board[i-1][j-1]="○ "; color=1; }else if(color==1){ board[i-1][j-1]="Q "; color=0; } flag=true; } return flag; } public int random(){ return (int)Math.round(Math.random()*(BOARD_SIZE-1)+1); } //flag为true时,游戏结束 public Boolean gameOver(int xpos,int ypos){ Boolean flag=false; xpos=xpos-1; ypos=ypos-1; //横向查看 int countx=0; for(int i=ypos;i<BOARD_SIZE;i++){ if(board[xpos][i].equals(board[xpos][ypos])){ countx=countx+1; }else{ break; } } for(int i=ypos ;i>0;i--){ if(board[xpos][i].equals(board[xpos][ypos])){ countx=countx+1; }else{ break; } } if(countx>=5){ flag=true; System.out.println("胜负已分"); return flag; } /*//纵向查看 int county=0; for(int i =xpos ;i<BOARD_SIZE;i++){ if(board[i][ypos].equals(board[xpos][ypos])){ county++; }else { break; } } for(int i=xpos;i>0;i--){ if(board[i][ypos].equals(board[xpos][ypos])){ county++; }else{ break; } } if(county>=5){ flag=true; return flag; } //左斜查看 int counta=1; for(int i =1;i<5;i++){ if(xpos+i<BOARD_SIZE&&ypos+i<BOARD_SIZE){ if(board[xpos+i][ypos+i].equals(board[xpos][ypos])){ counta++; }else{ break; } } } for(int i=1;i<5;i++){ if(xpos-i>0&&ypos-i>0){ if(board[xpos-i][ypos-i].equals(board[xpos][ypos])){ counta++; }else{ break; } } } if(counta>=5){ flag=true; return flag; }*/ //右斜查看 //棋盘查看 return flag; } public static void main(String []args) throws NumberFormatException, IOException{ Gobang gb=new Gobang(); System.out.println("—————————————————五子棋游戏—————————————————"); System.out.println("请输入1~"+BOARD_SIZE+"的数字"); gb.initBoard(); //get输入,用,分离 BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String inputStr = null; // br.readLine():每当在键盘上输入一行内容按回车,用户刚输入的内容将被br读取到。 while ((inputStr = br.readLine()) != null) { // 将用户输入的字符串以逗号(,)作为分隔符,分隔成2个字符串 if(!inputStr.contains(",")){ System.out.println("需要输入英文逗号哦,请重新输入~"); continue; } String[] posStrArr = inputStr.split(","); // 将2个字符串转换成用户下棋的座标 int xPos = Integer.parseInt(posStrArr[0]); int yPos = Integer.parseInt(posStrArr[1]); if(xPos<1||xPos>BOARD_SIZE||yPos<1||yPos>BOARD_SIZE){ System.out.println("请输入1~"+BOARD_SIZE+"的数字"); continue; } if(gb.paint(xPos,yPos)){ gb.showBoard(); if(gb.gameOver(xPos,yPos)){ break; } }else{ System.out.println("当前位置已有棋子,请重新落子"); continue; } while(true){ int xpos; int ypos; if(gb.paint( xpos=gb.random(),ypos=gb.random())){ gb.showBoard(); gb.gameOver( xpos,ypos); break; }else{ continue; } } } } }
梭哈游戏简易版
这个好久之前就看过,然后没写过,因为不懂梭哈怎么玩。。。。
还是没太懂,感觉是1张暗牌,然后依次发4张明牌,每发一轮来一轮跟/弃,发完后明牌分胜负。
唔。。。。五子棋的今天看了下官方给的正确答案,感觉自己的类设计很辣鸡。。。。梭哈感觉又要扑街。
第一步:流程图
这个逻辑太机儿复杂了,简化了一下:
这里实现大概有5个重点:
1.牌面设计
2.发牌随机
3.人工输入 Y/N
4.判定当前对局人数(有人弃牌,另一人就胜利了,这里没有考虑多人游戏)
5.比牌逻辑(同花顺>四条>葫芦>同花>顺子>三条>二对>单对>散牌 、黑桃>红桃>草花>方块 、A>K>Q>J>10>9>8 >7>6>5>4>3>2)
审题:
定义一个类,该类用户封装一桌梭哈游戏,这个类应该包含桌上剩下的牌的信息,并包含5个玩家的状态信息:各自的位置,游戏状态(正在游戏/已放弃),手上已有的牌等信息。如果有可能,这个类还应该实现发牌方法,这个方法需要控制从谁开始发牌,不要发牌给放弃的人,并修改桌上剩下的牌。
暂未实现比牌功能
package chapter6; /** * @param WEEK 牌面数值 * @param suit 花色 * @param poker[] 扑克牌字符串数组 */ class Stud{ /** * 返回 {@code String}是初始化的牌面, * @return 由52张不同牌面组成的字符串 */ public final static int CARD_NO=52; public final static String WEEK="A23456789TJQK"; public final static String SUIT="♠♥♦♣"; public String pokercard; public String restcard; public String getRestcard() { return restcard; } public void setRestcard(String restcard) { this.restcard = shuffleCard(pokercard); } public String getPokercard() { return pokercard; } public void setPokercard() { String poker=""; for(int j=0;j<SUIT.length();j++){ for(int k=0;k<WEEK.length();k++){ poker=poker+SUIT.substring(j, j+1)+WEEK.substring(k, k+1); } } this.pokercard= poker; } /** * 返回 {@code String}是洗牌后的牌面结果, * 给一个[0,52)的随机数,然后从给定的牌里面,按照随机数取出来,付给新牌面 * 并将旧牌面的该随机数的牌replace * @param pokercard a {@code String} value. * @return 将pokercard洗牌后的结果 */ public static String shuffleCard(String pokercard){ String sc = ""; String pc=pokercard; if(pokercard.length()!=CARD_NO*2){ System.out.println("the pokercard is wrong,please check the num"); return ""; } while(pc.length()>0){ int randomNum=(int)Math.floor(Math.random()*(pc.length()/2)); String card=pc.substring(2*randomNum, 2*randomNum+2); sc=sc+card; pc=pc.replace(card, ""); } return sc; } /** * 返回 发给玩家的手牌,并减少剩下的公牌,并更新玩家手牌 * @param restcard 参数是用来发牌的公牌 * */ public String handCard(String restcard,Player player){ String dc=""; dc =restcard.substring(0,2); this.restcard=this.restcard.substring(2); player.setCard(player.getCard()+dc); return dc; } /** * 比牌 */ // public void } /** * @author zhizhiyin * @param name 玩家名字; * @param position 玩家位置; * @param fold 是否弃牌,默认false不弃牌; * @param card 玩家手牌 */ class Player{ private String name ; private int position; private String card=""; private boolean fold=false;//弃牌 public String getCard() { return card; } public void setCard(String card) { if(card.length()==2){ //||card.matches("^[A|2|3|4|5|6|7|8|9|T|J|Q|K]{1}[♠|♥|♦|♣]{1}$") this.card = card; return ; } else{ System.out.println("传入的card 长度不为2"); } } public String getName() { return name; } public void setName(String name) { if(name.length()>=1&&name.length()<=4){ this.name = name; return; }else{ System.out.println("name长度须在1~4之间"); } } public int getPosition() { return position; } public void setPosition(int position) { if(position>=0&&position<5){ this.position = position; return ; }else{ System.out.println("position长度须在0~4之间"); } } public boolean getFold() { return fold; } public void setFold(boolean fold) { this.fold = fold; } //创建玩家,如果只需要五个玩家呢?怎么给这些玩家初始化呢? /** * @param name 玩家的名字 * @param positioni 玩家的位置 */ public Player(String name ,int position){ setName(name); setPosition(position); } /** * @param player 需要切换成弃牌状态的玩家 * @method turnFold(player) 如果用户未弃牌,置状态为弃牌,返回true,如果用户已经弃牌,置状态为false,表示转换失败,该用户已是弃牌状态 */ public boolean turnFold(){ if(this.getFold()==false){ this.setFold(true); return true; }else{ return false; } } } public class TestStud { public static void main(String[]args){ } }
加入测试代码,并修复了一些bug
比牌逻辑并未完善,明牌暗牌什么的也没有加上。
package chapter6; import java.util.Scanner; /** * @param WEEK 牌面数值 * @param suit 花色 * @param poker[] 扑克牌字符串数组 */ class Stud{ /** * 返回 {@code String}是初始化的牌面, * @return 由52张不同牌面组成的字符串 */ public final static int CARD_NO=52; public final static String WEEK="A23456789TJQK"; public final static String SUIT="♠♥♦♣"; public String getPokercard() { String poker=""; for(int j=0;j<SUIT.length();j++){ for(int k=0;k<WEEK.length();k++){ poker=poker+SUIT.substring(j, j+1)+WEEK.substring(k, k+1); } } return poker; } /** * 返回 {@code String}是洗牌后的牌面结果, * 给一个[0,52)的随机数,然后从给定的牌里面,按照随机数取出来,付给新牌面 * 并将旧牌面的该随机数的牌replace * @param pokercard a {@code String} value. * @return 将pokercard洗牌后的结果 */ public String shuffleCard(String pokercard){ String sc = ""; String pc=pokercard; if(pokercard.length()!=CARD_NO*2){ System.out.println("the pokercard is wrong,please check the num"); return ""; } while(pc.length()>0){ int randomNum=(int)Math.floor(Math.random()*(pc.length()/2)); String card=pc.substring(2*randomNum, 2*randomNum+2); sc=sc+card; pc=pc.replace(card, ""); } return sc; } /** * 返回 发给玩家的手牌,并更新玩家手牌 * @param restcard 参数是用来发牌的公牌 * */ public String handCard(String restcard,Player player){ String dc=""; dc =restcard.substring(0,2); System.out.println("handCard前,player的card是:"+player.getCard()); player.setCard(player.getCard()+dc); return dc; } public String restCard(String restCard){ return restCard.substring(2); } /** * 比牌 */ // public void } /** * @author zhizhiyin * @param name 玩家名字; * @param position 玩家位置; * @param fold 是否弃牌,默认false不弃牌; * @param card 玩家手牌 */ class Player{ private String name ; private int position; private String card=""; private boolean fold=false;//弃牌 public String getCard() { return card; } public void setCard(String card) { this.card = card; } public String getName() { return name; } public void setName(String name) { if(name.length()>=1&&name.length()<=4){ this.name = name; return; }else{ System.out.println("name长度须在1~4之间"); } } public int getPosition() { return position; } public void setPosition(int position) { if(position>=0&&position<5){ this.position = position; return ; }else{ System.out.println("position长度须在0~4之间"); } } public boolean getFold() { return fold; } public void setFold(boolean fold) { this.fold = fold; } //创建玩家,如果只需要五个玩家呢?怎么给这些玩家初始化呢? /** * @param name 玩家的名字 * @param positioni 玩家的位置 */ public Player(String name ,int position){ setName(name); setPosition(position); } /** * @param player 需要切换成弃牌状态的玩家 * @method turnFold(player) 如果用户未弃牌,置状态为弃牌,返回true,如果用户已经弃牌,置状态为false,表示转换失败,该用户已是弃牌状态 */ public boolean turnFold(){ if(this.getFold()==false){ this.setFold(true); return true; }else{ return false; } } } public class TestStud { public static void main(String[]args){ //怎么在初始化的时候创建玩家呢?怎么同时给五个玩家发牌呢? //用数组来解决 int playerNo=5;//人数 int flopNo=1;//轮次 Player []player=new Player[playerNo]; for(int i =0;i<playerNo;i++){ String name="玩家"+i; player[i]=new Player(name,i); } //洗牌 Stud s=new Stud(); String restCard =s.shuffleCard(s.getPokercard()); Boolean flag=false; while (!flag){ for(int i =0;i<player.length;i++){ //判断是否弃牌 if(player[i].getFold()==false){ s.handCard(restCard, player[i]); restCard=s.restCard(restCard); System.out.println("当前余牌:"+restCard); //跟弃 System.out.println(player[i].getName()+"的手牌:"+player[i].getCard()); System.out.println("当前玩家是否弃牌?Y/N"); Scanner input = new Scanner(System.in); String str =input.next(); if (str.equals("Y")){ //弃牌 player[i].turnFold(); playerNo=playerNo-1; System.out.println("playerNo:"+playerNo); } if(playerNo==1){ //结束 System.out.println("game over"); flag=true; break; } } } flopNo=flopNo+1; if(flopNo==5){ System.out.println("进入比牌"); flag=true; break; } } } }
梭哈游戏 阉割版
需要把毛坯版改成精装版。。。。
老规矩,流程图:
之前的版本,用数组和字符串写的。chapter7讲的是集合。
总体优化方向应该是用集合来写。
优化方向:
1.手牌需要区分 明牌/暗牌。
2.洗牌似乎可以用set来写?
3.比牌逻辑不会哦。。。这个怎么比较呢?
准备把集合看完了再来大改一下。
package chapter6; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Scanner; /** * @param WEEK 牌面数值 * @param suit 花色 * @param poker[] 扑克牌字符串数组 */ class Stud{ public final static int CARD_NO=52; public final static String WEEK="A23456789TJQK"; public final static String SUIT="♠♥♦♣"; /** * 返回 {@code ArrayList}是初始化的牌面, * @return ArrayList 为初始化赋值的牌面 */ public ArrayList initPokerCard() { ArrayList poker=new ArrayList(); for(int j=0;j<SUIT.length();j++){ for(int k=0;k<WEEK.length();k++){ poker.add(SUIT.substring(j, j+1)+WEEK.substring(k, k+1)); } } return poker; } /** * 返回 {@code ArrayList}是洗牌后的牌面结果, * 给一个[0,52)的随机数,然后从给定的牌里面,按照随机数取出来,add给新牌面 * 并将旧牌面的该随机数的牌remove * @param pokercard a {@code ArrayList} value. * @return 将poker洗牌后的结果 */ public ArrayList shuffleCard(ArrayList poker){ ArrayList al=new ArrayList(); while(poker.size()>0){ int randomNum=(int)Math.floor(Math.random()*(poker.size())); al.add(poker.get(randomNum)); poker.remove(randomNum); } return al; } /** * 返回 {@code String}发给玩家的手牌,并更新玩家手牌 * @param poker 参数是用来发牌的公牌 * */ public String handCard(ArrayList poker,Player player){ String handCard=""; handCard=(String) poker.get(0); System.out.println("handCard前,player的card是:"+player.getCard()); player.setCard(player.getCard()+handCard); return handCard; } /** * {@code ArrayList}将第一张牌移除,返回剩余的牌面 * @param poker 当前剩余公牌 * 模拟发牌 */ public ArrayList restCard(ArrayList poker){ poker.remove(0); return poker; } /** * 比牌 */ public Player judge(HashMap player){ Player winner =(Player)player.get(0); //遍历,如果第一个大,就将第一个和第N个的位置调换 return winner; } } /** * @author zhizhiyin * @param name 玩家名字; * @param position 玩家位置; * @param fold 是否弃牌,默认false不弃牌; * @param card 玩家手牌 */ class Player{ private String name ; private String card=""; private boolean fold=false;//弃牌 public String getCard() { return card; } public void setCard(String card) { this.card = card; } public String getName() { return name; } public void setName(String name) { if(name.length()>=1&&name.length()<=4){ this.name = name; return; }else{ System.out.println("name长度须在1~4之间"); } } public boolean getFold() { return fold; } public void setFold(boolean fold) { this.fold = fold; } //创建玩家,如果只需要五个玩家呢?怎么给这些玩家初始化呢? /** * @param name 玩家的名字 * @param positioni 玩家的位置 */ public Player(String name){ setName(name); } /** * @param player 需要切换成弃牌状态的玩家 * @method turnFold(player) 如果用户未弃牌,置状态为弃牌,返回true,如果用户已经弃牌,置状态为false,表示转换失败,该用户已是弃牌状态 */ public boolean turnFold(){ if(this.getFold()==false){ this.setFold(true); System.out.println("该玩家弃牌"); return true; }else{ return false; } } } public class TestStud { public static void main(String[]args){ //给玩家赋值 int playerNo=5; HashMap player=new HashMap(); for(int i =0;i<playerNo;i++){ String name ="玩家"+i; player.put(i, new Player(name)); } Stud s = new Stud(); ArrayList poker =s.initPokerCard();//初始化牌面 poker = s.shuffleCard(poker);//洗牌 int flopNo=1;//轮次 Boolean flag=false; while (!flag){ for(int i =0;i<player.size();i++){ Player currentPlayer =(Player)player.get(i); if(player.size()==1){ //结束 System.out.println("当前仅有一个玩家:"+currentPlayer.getName()+",game over"); flag=true; break; } s.handCard(poker,currentPlayer); poker=s.restCard(poker); System.out.println("当前余牌:"+poker); //跟弃 System.out.println(currentPlayer.getName()+"的手牌:"+currentPlayer.getCard()); System.out.println("当前玩家是否弃牌?Y/N"); Scanner input = new Scanner(System.in); String str =input.next(); if (str.equals("Y")){ //弃牌 currentPlayer.turnFold(); player.remove(i); } } flopNo=flopNo+1; if(flopNo==5){ System.out.println("进入比牌"); s.judge(player); flag=true; break; } } } }
比牌逻辑未修改,感觉这个好难哦。
有一点思路:
1.如果是牌桌的话,可以用冒泡排序依次排列,然后算钱,这里会简化一下,只找出最大的牌面,并返回player,这里我的player用的hashMap。取值的话只能依靠index。
取出最小值:
int min =numList[0]; int exchange=0; //筛选出最小的,并显示 for(int i=1;i<numList.length;i++){ if(numList[i]<min){ exchange=min; min=numList[i]; numList[i]=exchange; } }
冒泡排序
int ex = 0; for (int i = numList.length; i>1; i--) { for (int j = 1; j < i; j++) { if (numList[j] < numList[j - 1]) { ex = numList[j - 1]; numList[j - 1] = numList[j]; numList[j] = ex; } } }
2.需要写详细的1v1的手牌比较。需要分别比较花色,牌面。。。我讨厌写这个
判断牌型,同花顺,同花,顺子
public int levelOfCard(String handCard) { int level = 0; String week = ""; if (handCard.length() > 10 || handCard.length() <= 0) { System.out.println("字符串长度异常"); return -1; } int color = 1; // 判断同花的 for (int i = 2; i < handCard.length(); i = i + 2) { char x = handCard.charAt(i); char last = handCard.charAt(i - 2); if (SUIT.indexOf(x) == SUIT.indexOf(last)) { color++; } else if (x != last) { break; } } // 判断顺子的 for (int i = 1; i < handCard.length(); i = i + 2) { week = week + handCard.substring(i, i + 1); } // 判断同花顺,同花,顺子 if (color == 5 && WEEK.contains(week)) { return 1; } else if (color == 5 && (!WEEK.contains(week))) { return 4; } else if (color != 5 && WEEK.contains(week)) { return 5; } // 判断同week出现的次数 int maxTimes=1; for (int i = 1; i < week.length(); i++) { //how????? } return level; } }
判断其他牌型,金刚,葫芦,三条,两对,一对,单牌
这里写了一个判断字符串中重复次数最多的字符和重复次数。。。。
感觉代码质量特别差,这里用的是hashMap,准备看看别人怎么处理的。
String str="a112222233344444556"; int count=1; char maxStr='*'; HashMap hm = new HashMap(); for(int i =1;i<str.length();i++){ if(str.charAt(i)==str.charAt(i-1)){ count++; }else if(i<str.length()-1){ hm.put(str.charAt(i-1), count); count=1; }else if(i==str.length()-1){ hm.put(str.charAt(i), count); count=0; } } for(Object key:hm.keySet()){ int value=(Integer) hm.get(key); if(value>count){ count=value; maxStr=(Character) key; } } System.out.println("出现最多的字符是:"+maxStr+"count:"+count);
没有看别人的代码,修改了一下赋值逻辑
String str="a112222233344444556"; int countMax=1; int count=1; char maxchar=str.charAt(0); for(int i =1;i<str.length();i++){ //计算count,将第一个count和char赋值给max if(str.charAt(i)==str.charAt(i-1)){ count++; }else if(count>countMax){ countMax=count; maxchar=str.charAt(i-1); count=1; }else{ count=1; } } System.out.println("出现最多的字符是:"+maxchar+",countMax:"+countMax);
同level的比牌没有完成:
package chapter6; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Scanner; import org.omg.Messaging.SyncScopeHelper; /** * @param WEEK * 牌面数值 * @param suit * 花色 * @param poker[] * 扑克牌字符串数组 */ class Stud { public final static int CARD_NO = 52; public final static String WEEK = "A23456789TJQK"; public final static String SUIT = "♠♥♦♣"; /** * 返回 {@code ArrayList}是初始化的牌面, * * @return ArrayList 为初始化赋值的牌面 */ public ArrayList initPokerCard() { ArrayList poker = new ArrayList(); for (int j = 0; j < SUIT.length(); j++) { for (int k = 0; k < WEEK.length(); k++) { poker.add(SUIT.substring(j, j + 1) + WEEK.substring(k, k + 1)); } } return poker; } /** * 返回 {@code ArrayList}是洗牌后的牌面结果, 给一个[0,52)的随机数,然后从给定的牌里面,按照随机数取出来,add给新牌面 * 并将旧牌面的该随机数的牌remove * * @param pokercard * a {@code ArrayList} value. * @return 将poker洗牌后的结果 */ public ArrayList shuffleCard(ArrayList poker) { ArrayList al = new ArrayList(); while (poker.size() > 0) { int randomNum = (int) Math.floor(Math.random() * (poker.size())); al.add(poker.get(randomNum)); poker.remove(randomNum); } return al; } /** * 返回 {@code String}发给玩家的手牌,并更新玩家手牌 * * @param poker * 参数是用来发牌的公牌 * */ public String handCard(ArrayList poker, Player player) { String newCard = (String) poker.get(0);// 发过来的牌 String handCard = player.getCard();// 本来的牌 System.out.println("NEW:" + newCard + ",handCard:" + handCard); int newIndex = WEEK.indexOf(newCard.charAt(1)); if (handCard.equals("")) { handCard = newCard; player.setCard(handCard); System.out.println("handCard:" + handCard); return handCard; } else { for (int i = 1; i < handCard.length(); i = i + 2) { if (newIndex <= WEEK.indexOf(handCard.charAt(i))) { handCard = handCard.substring(0, i - 1) + newCard + handCard.substring(i - 1, handCard.length()); player.setCard(handCard); return handCard; } else if (newIndex > WEEK.indexOf(handCard.charAt(i)) && i == handCard.length() - 1) { handCard = handCard + newCard; player.setCard(handCard); return handCard; } } } return handCard; } /** * {@code ArrayList}将第一张牌移除,返回剩余的牌面 * * @param poker * 当前剩余公牌 模拟发牌 */ public ArrayList restCard(ArrayList poker) { poker.remove(0); return poker; } /** * 比牌 */ public Player judge(HashMap player) { Player winner = (Player) player.get(0); // 遍历,如果第一个大,就将第一个和第N个的位置调换 for (int i = 1; i < player.size(); i++) { Player next = (Player) player.get(i); // 比较两者,如果手牌next>winner ,返回true,反之,返回false if (compare(next.getCard(), winner.getCard())) { winner = next; } } return winner; } /** * 默认值是false,如果a的牌更大,就将player置为b * * @param 用来比较的牌 * @param 当前的winner的牌 * @return 前者比后者大,返回true,否则返回false */ public Boolean compare(String handCardA, String handCardB) { Boolean flag = false; // 先判断牌面level,再判断牌面大小 int levelA = levelOfCard(handCardA); int levelB = levelOfCard(handCardB); if (levelA > levelB) { return true; } else if (levelA < levelB) { return false; } else if(levelA==levelB) { //同牌型比牌: switch (levelA) { // 同花顺 case 1: // 金刚 case 2: // 葫芦 case 3: // 同花 case 4: // 顺子 case 5: //other } } return flag; } public int levelOfCard(String handCard) { int level = 0; String week = ""; if (handCard.length() > 10 || handCard.length() <= 0) { System.out.println("字符串长度异常"); return -1; } int color = 1; // 判断同花的 for (int i = 2; i < handCard.length(); i = i + 2) { char x = handCard.charAt(i); char last = handCard.charAt(i - 2); if (SUIT.indexOf(x) == SUIT.indexOf(last)) { color++; } else if (x != last) { break; } } // 判断顺子的 for (int i = 1; i < handCard.length(); i = i + 2) { week = week + handCard.substring(i, i + 1); } // 判断同花顺,同花,顺子 if (color == 5 && WEEK.contains(week)) { System.out.println("同花顺"); return 1; } else if (color == 5 && (!WEEK.contains(week))) { System.out.println("同花"); return 4; } else if (color != 5 && WEEK.contains(week)) { System.out.println("顺子"); return 5; } // 判断同week出现的次数 int countMax=1; int count=1; char maxchar=week.charAt(0); for(int i =1;i<week.length();i++){ //计算count,将第一个count和char赋值给max if(week.charAt(i)==week.charAt(i-1)){ count++; }else{ count=1; } if(count>countMax){ countMax=count; maxchar=week.charAt(i-1); } } if(countMax ==4){ System.out.println("金刚"); return 2; }else if(countMax ==3){ String str = maxchar+""; String [] str2=week.split(str); str=""; for(String s:str2){ str=str+s; } if(getMaxCount(str)==2){ System.out.println("葫芦"); return 3; }else{ System.out.println("三条"); return 6; } }else if(countMax==2){ String str = maxchar+""; String [] str2=week.split(str); str=""; for(String s:str2){ str=str+s; } if(getMaxCount(str)==2){ System.out.println("两对"); System.out.println("str:"+str); return 7; }else { System.out.println("一对"); System.out.println("str:"+str); return 8; } }else if(countMax==1){ System.out.println("散牌"); return 9; } return level; } private int getMaxCount(String week) { int countMax=1; int count=1; // char maxchar=handCard.charAt(0); for(int i =1;i<week.length();i++){ //计算count,将第一个count和char赋值给max if(week.charAt(i)==week.charAt(i-1)){ count++; }else if(count>countMax){ countMax=count; // maxchar=handCard.charAt(i-1); count=1; }else{ count=1; } } return countMax; } } /** * @author zhizhiyin * @param name * 玩家名字; * @param position * 玩家位置; * @param fold * 是否弃牌,默认false不弃牌; * @param card * 玩家手牌 */ class Player { private String name; private String card = ""; private boolean fold = false;// 弃牌 public String getCard() { return card; } public void setCard(String card) { this.card = card; } public String getName() { return name; } public void setName(String name) { if (name.length() >= 1 && name.length() <= 4) { this.name = name; return; } else { System.out.println("name长度须在1~4之间"); } } public boolean getFold() { return fold; } public void setFold(boolean fold) { this.fold = fold; } // 创建玩家,如果只需要五个玩家呢?怎么给这些玩家初始化呢? /** * @param name * 玩家的名字 * @param positioni * 玩家的位置 */ public Player(String name) { setName(name); } /** * @param player * 需要切换成弃牌状态的玩家 * @method turnFold(player) * 如果用户未弃牌,置状态为弃牌,返回true,如果用户已经弃牌,置状态为false,表示转换失败,该用户已是弃牌状态 */ public boolean turnFold() { if (this.getFold() == false) { this.setFold(true); System.out.println("该玩家弃牌"); return true; } else { return false; } } } public class TestStud { public static void main(String[] args) { int playerNo = 5; Stud s = new Stud(); ArrayList poker = s.initPokerCard(); poker = s.shuffleCard(poker); HashMap player = new HashMap(); for (int i = 0; i < playerNo; i++) { String name = "玩家" + i; player.put(i, new Player(name)); } int flopNo = 1;// 轮次 Boolean flag = false; while (!flag) { for (int i = 0; i < player.size(); i++) { Player currentPlayer = (Player) player.get(i); if (player.size() == 1) { System.out.println("当前仅有一个玩家:" + currentPlayer.getName() + ",game over"); flag = true; break; } s.handCard(poker, currentPlayer); poker = s.restCard(poker); System.out.println("当前余牌:" + poker); // 跟弃 System.out.println(currentPlayer.getName() + "的手牌:" + currentPlayer.getCard()); System.out.println("当前玩家是否弃牌?Y/N"); Scanner input = new Scanner(System.in); String str = input.next(); if (str.equals("Y")) { // 弃牌 currentPlayer.turnFold(); player.remove(i); } } if (flopNo == 5) { System.out.println("进入比牌"); for(Object key :player.keySet()){ Player p =(Player)player.get(key); System.out.println(p.getCard()); System.out.println(s.levelOfCard(p.getCard())); } // s.judge(player); flag = true; break; } flopNo = flopNo + 1; } } }