# java 作業
:::spoiler 抽籤
## HW3
1. 樂透產生器
* 撰寫兩個類別
* 樂透產生器類別(LotteryGenerator.java)
* 樂透產生器類別中有一個成員變數
* 所有可以抽出的號碼,totalNumbers: int,例如totalNumbers=46,則可從1~46個數字中抽出號碼。
* 樂透產生器類別中定義一個靜態常數(int)。
* 抽出的號碼的個數,lotteryNumbers=5,(需從totalNumbers數字中抽出5個號碼。)
* 建立一個建構子
* 沒有參數的空建構子。
* 樂透產生器類別中有一個方法(generateLottery())用來隨機產生樂透號碼。
* 將隨機抽到的號碼以int[]型態回傳,須由小到大排序,此陣列長度為lotteryNumbers。
* 抽出的號碼不能重複。
* 使用Math.random()方法於隨機抽號碼。
* 樂透產生器類別中有一個**靜態**方法(average(int[] numbers))用來計算產生樂透號碼的平均值。
* 回傳值型態為double
* App類別(APP.java)
* 從上述樂透產生器類別定義,使用空建構子生成出一個物件。
* 由console輸入totalNumbers值。
* 如果totalNumbers小於lotteryNumbers常數,則告知使用者重新輸入,直到大於或等於lotteryNumbers常數。
* 呼叫generateLottery方法,產生樂透號碼。
* 輸出樂透號碼。
* 呼叫樂透產生器類別中的average()方法計算樂透號碼平均值,並輸出至小數點後兩位。
* 輸出範例如下(中英皆可),請依照下列格式輸出

:::
::: spoiler code
## app.java
```java=
import java.util.Arrays;
import java.util.Scanner;
public class APP {
public static void main(String[]args){
LotteryGenerator lot = new LotteryGenerator();
Scanner s = new Scanner(System.in);
lot.totalNumber=0;
while(lot.totalNumber<lot.lotteryNumber) {
System.out.print("請輸入可以抽出的號碼: ");
lot.totalNumber = s.nextInt();
}
int[] Arr = lot.generateLottery();
System.out.print("樂透號碼為: ");
for (int i=0;i<lot.lotteryNumber;i++){
System.out.print(Arr[i]+" ");
}
System.out.println();
System.out.printf("樂透號碼平均值: %.2f",lot.average(Arr));
}
}
```
## LotteryGenerator.java
```java=
import java.util.Arrays;
public class LotteryGenerator {
int totalNumber;
static final int lotteryNumber=5;
public LotteryGenerator(){
}
public int[] generateLottery(){
int[] arr=new int[lotteryNumber];
boolean[] check=new boolean[totalNumber+1];
Arrays.fill(check, false);
for(int i=0;i<lotteryNumber;i++){
int n=(int)(Math.random()*totalNumber)+1;
if(check[n]){
i--;
continue;
}
arr[i]=n;
check[n]=true;
}
Arrays.sort(arr);
return arr;
}
public static double average(int arr[]){
double num=0;
for(int i=0;i<lotteryNumber;i++){
num+=arr[i];
}
return num/lotteryNumber;
}
}
```
:::
:::spoiler 抽籤2
## HW4
1. 樂透產生器(二)
* 撰寫兩個類別
* 樂透產生器類別(LotteryGenerator.java)
* 樂透產生器類別中有一個成員變數
* 樂透結果陣列,lotteryResult: int[][] 。儲存所有樂透結果。
* 建立一個建構子
* 沒有參數的空建構子。
* 樂透產生器類別中有一個方法
(generateLottery(int totalNumbers, int lotteryNumbers))用來隨機產生樂透號碼。
* 使用Math.random()方法於隨機抽號碼。
* 抽出的號碼不能重複。
* 呼叫lotterySort()方法排序樂透號碼。
* 將排序好的的號碼以int[]型態回傳,此陣列長度為lotteryNumbers。
* 樂透產生器類別中有二個**靜態**方法
* 排序樂透號碼。 (lotterySort(int[] lottery))
* 將此樂透號碼由小到大排序。
* 無回傳值。
* 計算產生樂透號碼的平均值。(average(int[] numbers))。
* 計算樂透號碼平均值。
* 回傳值型態為double。
* App類別(APP.java)
* 從上述樂透產生器類別定義,使用空建構子生成出一個物件。
* 宣告兩個變數。
* totalNumbers: int,所有可以抽出的號碼,例如totalNumbers=46,則可從1~46個數字中抽出號碼。
* lotteryNumbers: int,抽出的號碼的個數,例如lotteryNumbers=5,則需從totalNumbers數字中抽出5個號碼。
* 由console輸入樂透的組別數量。
* 由console輸入totalNumbers、lotteryNumbers數值。
* 如果totalNumbers小於lotteryNumbers,則告知使用者重新輸入(重新輸入該組別即可),直到大於或等於lotteryNumbers。
* 每次呼叫generateLottery()方法,產生樂透號碼,存入此物件的樂透結果陣列。
* 輸出所有組別樂透號碼。
* 呼叫樂透產生器類別中的average()方法計算所有組別樂透號碼平均值,並輸出至小數點後兩位。
* 輸出範例如下(中英皆可),請依照下列格式輸出

:::
::: spoiler code
## app.java
```java=
import java.util.Arrays;
import java.util.Scanner;
public class APP {
public static void main(String[]args){
LotteryGenerator lot = new LotteryGenerator();
Scanner s = new Scanner(System.in);
int groupNum;
lot.lotteryResult = new int[10000][];
System.out.print("請輸入樂透組數: ");
groupNum = s.nextInt();
for(int i=0;i<groupNum;i++){
System.out.printf("第%d組\n",i+1);
System.out.print("請輸入抽出的號碼範圈: ");
lot.totalNumber = s.nextInt();
System.out.print("請輸入號碼的個數: ");
lot.lotteryNumber = s.nextInt();
if(lot.lotteryNumber > lot.totalNumber){
System.out.println("抽出的號碼範圞不能小於號碼的個數");
i--;
continue;
}
int[] Arr = lot.generateLottery();
lot.lotteryResult[lot.nowGroup++] = Arrays.copyOf( Arr, Arr.length);
}
System.out.println("樂透結果:\n");
for(int i=0;i< groupNum;i++){
System.out.printf("第%d組結果: ",i+1);
for (int j=0;j<lot.lotteryResult[i].length;j++){
System.out.print(lot.lotteryResult[i][j]+" ");
}
System.out.println();
System.out.printf("樂透號碼平均值: %.2f\n",lot.average(lot.lotteryResult[i]));
}
}
}
/*
測資
5
6
5
7
9
9
7
4
3
5
2
7
5
*/
```
## LotteryGenerator.java
```java=
import java.util.Arrays;
public class LotteryGenerator {
int totalNumber;
static int lotteryNumber;
int nowGroup=0;
int lotteryResult[][];
public LotteryGenerator(){
}
public int[] generateLottery(){
int[] arr=new int[lotteryNumber];
boolean[] check=new boolean[totalNumber+1];
Arrays.fill(check, false);
for(int i=0;i<lotteryNumber;i++){
int n=(int)(Math.random()*totalNumber)+1;
if(check[n]){
i--;
continue;
}
arr[i]=n;
check[n]=true;
}
//Arrays.sort(arr);
lotterySort(arr);
System.out.println(Arrays.toString(arr));
return arr;
}
public static double average(int arr[]){
double num=0;
for(int i=0;i<arr.length;i++){
num+=(double)arr[i];
}
return num/arr.length;
}
public static void lotterySort(int[] lottery){
Arrays.sort(lottery);
}
}
```
:::
:::spoiler 火車
## HW5
1. 交通工具
* 撰寫四個類別,題目要求如下:
* 類別 Railway.java
* 此類別中有兩個私有成員變數,請提供相對應的 Accessor(Getter)以及Mutator(Setter)公開方法。
* conductorName: String (conductor:列車長)
* passenger: int
* 此類別中有一個針對 conductorName 以及 passenger 做初始化的建構子。
* 此類別中有一個公開方法 getInfo(),並將此方法定義為 **無法覆寫(override)** 的方法。
```
public String getInfo() {
return conductorName + "\t" + passenger
}
```
* 類別 Train.java
* 繼承前述類別Railway。
* 此類別中有一個額外的私有成員變數,請提供相對應的 Accessor(Getter)以及Mutator(Setter)公開方法。
* fare: double
* 建立一個建構子
* 針對conductorName、passenger、fare 做初始化。
* 此類別中有一個公開方法,價錢計算方式calcPrice()。
* 計算方式為 fare*passenger
* 回傳值為double。
* 無傳入參數
* 類別 HighSpeedRail.java
* 繼承前述類別Railway。
* 此類別中有一個額外的私有成員變數,請提供相對應的 Accessor(Getter)以及Mutator(Setter)公開方法。
* ticket: int
* 建立一個建構子
* 針對conductorName、passenger、ticket 做初始化。
* 此類別中有一個公開方法,價錢計算方式calcPrice()。
* 計算方式為 ticket*passenger
* 回傳值為int。
* 無傳入參數
* 類別 Main.java
* 建立一個長度為 3 的 Array(base class: Railway)。
* **隨機生成** 3 個物件並要求使用者輸入該物件所需資料,並放入 Array 中,隨機生成的物件必須是 Train 或 HighSpeedRail。並提醒使用者目前輸入的是何種變數。
* 若物件為Train,則輸入conductorName、passenger、fare。
* 若物件為HighSpeedRail,則輸入conductorName、passenger、ticket。
* 使用getInfo() 輸出 Railway Array 中每個物件的conductor、passenger。
* 輸出 Railway Array 中**每個Train物件**的passenger以及計算後的價錢。
* 輸出範例如下:

:::
::: spoiler code
## Main.java
```java=
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner ss=new Scanner(System.in);
Railway[] arr = new Railway[3];
for(int i=0;i<3;i++){
int n=(int)(Math.random()*2);
String name;
int passenger;
if(n==0){//Train
double fare;
System.out.print("Input train conductorName:");
//if(i!=0)ss.nextLine();
name=ss.next();
//System.out.println(name);
System.out.print("Input train passenger:");
passenger=ss.nextInt();
System.out.print("Input train fare:");
fare=ss.nextDouble();
arr[i]=new Train(name,passenger,fare);
}else if(n==1){//HighSpeedRail
int ticket;
System.out.print("Input high speed rail conductorName:");
//if(i!=0)ss.nextLine();
name=ss.next();
//System.out.println(name);
System.out.print("Input high speed rail passenger:");
passenger=ss.nextInt();
System.out.print("Input high speed rail ticket:");
ticket=ss.nextInt();
arr[i]=new HighSpeedRail(name,passenger,ticket);
}
}
System.out.println("\nAll conductor and passenger");
for(int i=0;i<3;i++){
System.out.println(arr[i].getInfo());
}
System.out.println("\nTrain passenger and price");
for(int i=0;i<3;i++){
if(arr[i] instanceof Train){
System.out.printf("train passenger: %d, train price: %.1f\n",arr[i].getPassenger(),((Train) arr[i]).calcPrice());
}
}
}
}
```
## Railway.java
```java=
public class Railway {
private String conductorName;
private int passenger;
public Railway(String conductorName ,int passenger){
this.conductorName=conductorName;
this.passenger=passenger;
}
public void setConductorName(String conductorName) {
this.conductorName = conductorName;
}
public void setPassenger(int passenger) {
this.passenger = passenger;
}
public String getConductorName() {
return conductorName;
}
public int getPassenger(){
return passenger;
}
public String getInfo(){
return conductorName + "\t" + passenger;
}
}
```
## Train.java
```java=
public class Train extends Railway{
private double fare;
public Train(String conductorName,int passenger, double fare){
super(conductorName,passenger);
this.fare=fare;
}
public double calcPrice(){
return getPassenger()*fare;
}
public double getFare() {
return fare;
}
public void setFare(double fare) {
this.fare = fare;
}
}
```
## HighSpeedRail.java
```java=
public class HighSpeedRail extends Railway{
private int ticket;
public HighSpeedRail(String conductorName, int passenger,int ticket) {
super(conductorName, passenger);
this.ticket=ticket;
}
public int getTicket() {
return ticket;
}
public void setTicket(int ticket) {
this.ticket = ticket;
}
public double calcPrice(){
return getPassenger()*ticket;
}
}
```
:::
::: spoiler 火車2
## HW6
1. 交通工具(二)
* 依照題目敘述建立各package,並在其中撰寫類別,題目要求如下:
* 建立package,名稱為 fcu.oop.traffic。並在其中撰寫以下類別。
* 公開類別 Transportation.java。
* 此類別中有兩個私有成員變數,請提供相對應的 Accessor(Getter)公開方法。
* driver: String
* price: double
* 此類別中有一個針對 driver 以及 price 做初始化的建構子。
* 此類別中有一個公開方法 calcPrice()。
```
public double calcPrice() {
return 0.5
}
```
* 公開類別 Train.java以及類別 Taxi.java。
* 這兩個類別皆繼承前述類別 Transportation 。
* 並根據以下表格定義類別,並覆寫對應方法。
||Train|Taxi|
|----------|------|--------|
|額外成員變數|road|way|
|成員變數型態|double|int|
|價錢計算方式(calcPrice)|price*road|price*way|
* 以上變數皆為私有變數,請提供相對應的 Accessor(Getter)公開方法。
* Train 類別的建構子針對 driver、price、road 做初始化。
* Taxi 類別的建構子針對 driver、price、way 做初始化。
* 建立package,名稱為 fcu.main。並在其中撰寫以下類別。
* 公開類別 Main.java。
* 建立一個長度為 3 的 Array(base class: Transportation)。
* 隨機生成 3 個物件並要求使用者輸入該物件所需資料,並放入 Array 中,隨機生成的物件必須是 Train 或 Taxi。並提醒使用者目前輸入的是何種變數。
* 輸出陣列中所有物件driver、計算後的價格(呼叫calcPrice())。
* 輸出範例如下:

* 資料夾階層:

:::
::: spoiler code
資料夾位置

## Main.java
```java=
package fcu.main;
import fcu.opp.traffic.*;
import java.util.Scanner;
public class Main {
public static void m1ain(String[] args) {
Scanner ss=new Scanner(System.in);
Transportation[] arr = new Transportation[3];
for(int i=0;i<3;i++){
int n=(int)(Math.random()*2);
String name;
double price;
if(n==0){//Train
double road;
System.out.print("Input train driver:");
name=ss.next();
System.out.print("Input train price:");
price=ss.nextDouble();
System.out.print("Input train road:");
road=ss.nextDouble();
arr[i]=new Train(name,price,road);
}else if(n==1){//HighSpeedRail
int way;
System.out.print("Input Taxi driver:");
name=ss.next();
System.out.print("Input Taxi price:");
price=ss.nextDouble();
System.out.print("Input Taxi way:");
way=ss.nextInt();
arr[i]=new Taxi(name,price,way);
}
}
System.out.println("\nTrain driver and price");
for(int i=0;i<3;i++){
if(arr[i] instanceof Train){
System.out.printf("train driver: %s, train price: %.1f\n",arr[i].getDriver(),((Train) arr[i]).calcPrice());
}
}
}
}
```
## Taxi.java
```java=
package fcu.opp.traffic;
public class Taxi extends Transportation {
private int way;
public Taxi(String driver, double price, int way) {
super(driver, price);
this.way=way;
}
public int getway() {
return way;
}
public void setway(int way) {
this.way = way;
}
@Override
public double calcPrice(){
return getPrice()*way;
}
}
```
## Train.java
```java=
package fcu.opp.traffic;
public class Train extends Transportation {
private double road;
public Train(String driver, double price, double road){
super(driver,price);
this.road=road;
}
public double getRoad() {
return road;
}
public void setRoad(double road) {
this.road = road;
}
@Override
public double calcPrice() {
return getPrice()*road;
}
}
```
## Transportation.java
```java=
package fcu.opp.traffic;
public class Transportation {
private String driver;
private double price;
public Transportation(String driver, double price){
this.driver=driver;
this.price=price;
}
public double getPrice() {
return price;
}
public String getDriver() {
return driver;
}
public void setDriver(String driver) {
this.driver = driver;
}
public void setPrice(double price) {
this.price = price;
}
public double calcPrice(){
return 0.5;
}
}
```
:::
::: spoiler 剪刀石頭布
## HW7
1. 剪刀石頭布
* 撰寫五個檔案,題目要求如下
* 公開Enum類別 Gesture.java
* 此類別定義 STONE, PAPER, SCISSORS (**全部大寫**)
* 公開介面 PlayGenerator.java
* 此介面中有一個 generateGestureByRandom() 方法
* 回傳資料型態為 Gesture 。
* 公開介面 PlayGround.java
* 此介面中有一個 play(Gesture[] user) 方法
* 傳入手勢(Gesture)陣列。
* 回傳資料型態為 String。
* 公開類別 GeneralGame.java
* 此類別實作 PlayGenerator 、 PlayGround 兩個介面。
* 此類別中有一個私有成員變數:
* sysGesture: Gesture[],陣列長度為3。
* 為此私有變數建立 Accessor(Getter)公開方法。
* 在 generateGestureByRandom() 公開方法中實作以下要求:
* 隨機生成遊戲手勢(Gesture)並回傳。
* 在 play(Gesture[] user) 公開方法中實作以下要求:
* 傳入使用者輸入的三個手勢(Gesture)
* 開始三場比賽,每場比賽皆要呼叫 generateGestureByRandom() 方法隨機生成手勢與使用者相比,並記錄比賽結果。
* 將系統手勢存入私有變數 sysGesture。
* 若使用者贏得比賽的次數大於輸掉比賽的次數則回傳 “You win!”
* 若使用者贏得比賽的次數等於輸掉比賽的次數則回傳 “Game tie”
* 若使用者贏得比賽的次數小於輸掉比賽的次數則回傳 “You lose!”
* 公開類別 Main.java
* 生成一個 GeneralGame 類別的物件。
* 在console輸入三個猜拳的字串。
* **輸入為小寫。**
* 若使用者輸入字串不符合三種猜拳手勢請使用者重新輸入,重新輸入該次手勢即可。
* 將輸入的猜拳字串轉換為Enum型態並存入陣列。
* 其陣列儲存的資料型態須為Gesture。
* 呼叫物件的 play() 方法,傳入上述使用者猜拳手勢陣列。
* 依序輸出所有系統手勢。
* 輸出回傳的比賽結果。
* 輸出範例如下。

:::
:::spoiler code
## Main.java
```java=
import java.util.Scanner;
public class Main {
public static void main(String[] args){
GeneralGame g=new GeneralGame();
Gesture[] gamer=new Gesture[3];
Scanner ss=new Scanner(System.in);
System.out.println("Please enter 3 gestures");
for (int i=0;i<3;i++){
try {
String str=ss.nextLine();
if(!str.equals("scissors") && !str.equals("paper") && !str.equals("stone")){
throw new Exception();
}else{
switch (str){
case "scissors":
gamer[i]=Gesture.SCISSOR;
break;
case "paper":
gamer[i]=Gesture.PAPER;
break;
case "stone":
gamer[i]=Gesture.STONE;
break;
}
}
}catch (Exception e){
System.out.println("wrong imput, please re-enter gesture");
i--;
continue;
}
}
System.out.println('\n'+"---All system gestures---");
String str= g.play(gamer);
for(Gesture result:g.getSysGesture() ){
System.out.println(result.toString().toLowerCase());
}
System.out.println(str);
}
}
/*
scissors
paaaaper
paper
scissors
*/
```
## PlayGenerator.java
```java=
public interface PlayGenerator {
public Gesture generateGestureByRandom();
}
```
## PlayGround.java
```java=
public interface PlayGround {
public String play(Gesture[] user);
}
```
## Gesture.java
```java=
public enum Gesture {
PAPER,//布
SCISSOR(),//剪刀
STONE;//石頭
}
```
## GeneralGame.java
```java=
public class GeneralGame implements PlayGenerator,PlayGround {
private Gesture[] sysGesture = new Gesture[3];
public String play(Gesture[] user){
int sum=0;
for(int i=0;i<3;i++){
sysGesture[i]=generateGestureByRandom();
if(user[i].ordinal()==2 && sysGesture[i].ordinal()==0){
sum--;
}else if(user[i].ordinal()==0 && sysGesture[i].ordinal()==2){
sum++;
}else if(user[i].ordinal()>sysGesture[i].ordinal()){
sum++;
}else if(user[i].ordinal()<sysGesture[i].ordinal()){
sum--;
}
}
if(sum>0)return "You win!";
else if (sum==0)return "Game tie";
else if (sum<0)return "You lose!";
return "null";
}
public Gesture generateGestureByRandom(){
return Gesture.values()[(int)(Math.random()*3)];
}
public Gesture[] getSysGesture() {
return this.sysGesture;
}
}
```
:::
::: spoiler 成績輸入
# HW9
1. 成績管理
* 撰寫兩個檔案,題目要求如下:
* 公開類別 Student.java
* 此類別中有三個私有成員變數,請提供相對應的 Accessor(Getter)以及Mutator(Setter)公開方法。
* name: String
* id: int
* grades: <String, Integer>,使用HashMap建立此物件,請將此變數的setter改寫為,public void setGrade(String subject, int grade),儲存時請將String轉成大寫。
* 此類別中有一個靜態陣列 allSubject ,裡面存放科目字串,請將陣列定義為以下內容。
* "Calculus", "Statistics", "Algorithm", "Math", "English" 。
* 此類別中有一個公開靜態方法 boolean subjectIsContained(String subject) ,在此方法中實作以下內容:
* 若參數subject有在allSubject中出現,請回傳true,否則回傳false。
* 比對時請忽略大小寫。
* 公開類別 Main.java
* 建立一個 Student 物件,並指定name、id。
* 輸入科目以及成績,並注意以下要求。
* 使用 subjectIsContained 方法,若使用者輸入科目不再陣列中,提醒使用者查無此科目。若存在於陣列中,則繼續輸入該科目成績。
* 輸入直到使用者輸入 exit 時結束。
* 輸出學生的 name 、 id。
* 輸出學生目前有幾個科目。
* 輸出所有存放在 grades 中的科目、成績。

:::
:::spoiler code
## Main.java
```java=
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
public class Main {
public static void main(String [] args){
Scanner ss=new Scanner(System.in);
Student stu=new Student("Andy",1001);
while (true){
String stuName;
int stuId;
System.out.print("Input subject:");
stuName=ss.next();
if(stuName.equals("exit"))break;
if(!stu.subjectlsContained(stuName)){
System.out.println("this subject:"+stuName+" not found");
continue;
}
System.out.print("Input grade:");
stuId=ss.nextInt();
stu.setGrades(stuName,stuId);
}
System.out.println("\nStudent name: "+stu.getName()+", id: "+stu.getId());
System.out.println("This student has "+stu.getGrades().size()+" subjects");
for(Map.Entry<String,Integer> i:stu.getGrades().entrySet()){
System.out.println("Subject: "+i.getKey()+", grade:"+i.getValue());
}
}
}
/*
math
90
English
60
Calsulussss
calculus
80
english
70
exit
*/
```
## Student.java
```java=
import java.util.HashMap;
enum allSubject{
Calculus,
Statistics,
Algorithm,
Math,
English;
}
public class Student {
private String name;
private int id;
private HashMap<String,Integer> grades = new HashMap<String,Integer>();
public Student(String name,int id){
this.name=name;
this.id=id;
}
boolean subjectlsContained(String subject){
boolean check=false;
for(allSubject i:allSubject.values()){
//System.out.println(subject.toLowerCase()+" "+i.name().toLowerCase());
if(subject.toLowerCase().equals(i.name().toLowerCase())) {
check = true;
}
}
return check;
}
public void setName(String name) {
this.name = name;
}
public void setId(int id) {
this.id = id;
}
public void setGrades(String subject,int grade) {
this.grades.put(subject.toUpperCase(),grade);
}
public String getName() {
return name;
}
public int getId() {
return id;
}
public HashMap<String, Integer> getGrades() {
return grades;
}
}
```
:::