---
# System prepended metadata

title: Javascript 第四章 流程控制與迴圈
tags: [JS X Codeshiba]

---

# Javascript 第四章 流程控制與迴圈
###### tags: `JS X Codeshiba`

## 決策流程的範例_Crown & Anchor
### 背景介紹
![](https://i.imgur.com/H9DZvhi.png)
![](https://i.imgur.com/Y2yHRym.png)

水手可以針對不同的花色來押寶，以下是各類情形他可以獲得的金錢:

| 賭注 | 骰子 | 贏錢 |
|:-------:|:-----:|:------:|
| Crown 5塊錢 |  Crown Crown Crown  | 15元 |
| Crown 5塊錢 |  Crown Crown Anchor | 10元 |
| Crown 5塊錢 |  Crown Heart Spade  | 5元 |
| Crown 5塊錢 |  Anchor Heart Spade  | 0元 |
| Crown 3塊錢 Spade 2塊錢 |  Crown Crown Crown  | 9元 |
| Crown 3塊錢 Spade 2塊錢 |  Crown Heart Spade  | 5元 |
| 每個格子都1塊錢 |  Anything  | 3元 |

假設有個人它的決策模式為，每次上岸都拿50元來玩，**只要贏到本錢的兩倍**，他就不玩了，只要他沒有達成目標，他就會**玩到沒錢為止**

此時我們可以把這個決策畫成流程圖
```flow
st=>start: 開始
cond1=>condition: 沒錢或贏到100?
op=>operation: 結束
op2=>operation: 下注
op3=>operation: 擲骰子
op4=>operation: 拿到錢(回到決策點)


st->cond1->op2->op3->op4->
cond1(yes)->op
cond1(no)->op2
```
### 解構
此時的決策圖還是有些模糊，我們需要限制流程圖的動作:
1. 變數賦值: funds=50, bets={}, hand = [],
2. 介於m跟n的隨機整數，包含首尾值: rand(1,6)
3. 隨機骰面字串("heart", "crown"等等):randFace()
4. 物件特性賦值:bets["heart"]=5、bets[randFace()]=5
5. 將元素加入陣列: hand.push(randFace())
6. 基本算術: funds - totalBet、funds + winnings
7. 遞增: roll++(代表把變數roll + 1)

在這裡，我們把要做成迴圈的部份給標示出來
![](https://i.imgur.com/0GwUmOi.png)

## 迴圈架構撰寫
要讓迴圈運轉的條件為`funds > 1 && funds < 100`
```javascript=
let funds = 50;
//起始條件
while(funds > 1 && funds < 100) {
//下注

//擲骰子

//拿贏得的錢
}
```
### 區塊陳述式(複合陳述式)
區塊陳述式是以大括號包起來的一系列陳述式，被視為一個單位來處理，雖然迴圈不用區塊陳述式也可以執行，例如:
```javascript=
// 沒有換行
while(funds > 1 && funds < 100) funds = funds + 2;
//沒有換行，裡面只有一個陳述式的區塊
while(funds > 1 && funds < 100){funds = funds + 2; }
```
為了避免縮排造成的問題，建議還是用區塊陳述式來進行撰寫

### 協助函式
在這個案例會需要兩個協助函式
```javascript=
//隨機回傳範圍[m,n](包括頭尾)之間的整數
function rand(m,n) {
    return m + Math.floor((n - m + 1)*Math.random());
}
```
```javascript=
//隨機回傳一個代表
//六個Crown and Anchor 圖案的字串
function randFace() {
    return ["crown", "anchor", "heart", "spade", "club", "diamond"]
    [rand(0,5)];
}
```
### 第一部分(下注): 情境一(if-else if -else判斷式)
範例
![](https://i.imgur.com/sLqiVVu.png)
我們的對象要掏出7塊錢來下注，但他有個怪癖
只要他掏出的是幸運數字7，他就會把錢全部壓在"Heart"那一格
![](https://i.imgur.com/VBHd29N.png)
```javascript=
const bets = {crown: 0, anchor: 0, heart: 0, spade:0, club:0, diamond: 0};
//先把賭注的類別列出來
let totalBet = rand(1, funds);
//賭注的金額從1到剩餘的本金數j目隨機取數
if(totalBet === 7) {
    //把七塊錢作為賭本，壓在heart上面
    totalBet = funds;
    bets.heart = totalBet;
} else {
    // 分發所有賭注
}
funds = funds - totalBet;
```

### 第一部分(下注): 情境二(do...while迴圈)
如果不是拿到7的話，咱們的對象就會把拿到的賭金隨意地放在各個方格中，而且有可能重複下注
![](https://i.imgur.com/7LVvy2i.png)
```javascript=
let remaining = totalBet;
do {
    let bet = rand(1, remaining); //隨機拿取剩餘的賭金
    let face = randFace(); //隨機選擇下注花色
    bets[face] = bets[face] + bet; //針對隨機選擇的花色來下注
    remaining = remaining - bet; //扣掉已經下注的賭金
} while(remaining > 0); //當還有剩餘賭金時持續的下注
```

### 第二部分(擲骰子):For迴圈
![](https://i.imgur.com/MhGWKIg.png)
for迴圈最適合需要作與固定次數的事情來使用，所以適合用來投擲固定次數的骰子，這次需要丟擲三次骰子(因為有三顆)。因為習慣用0作起始，所以我們的參數從0開始，在2結束。

此時的for迴圈包含三個部分:
1. 初始設定式
2. 條件
3. 最終運算式

```javascript=
const hand = [];
for(let roll = 0; roll < 3; roll++) {
    hand.push(randFace());
}
```

### 第三部分(拿回彩金):if陳述式

```javascript=
let winnings = 0;
for(let die=0; die < hand.length; die++) {
    let face = hand[die];
    if(bets[face] > 0) winnings = winnings + bets[face];
}
funds = funds + winnings;
```

### 整合
```javascript=
// returns a random integer in the range [m, n] (inclusive)
function rand(m, n) {
    return m + Math.floor((n - m + 1)*Math.random());
}

// randomly returns a string representing one of the six
// Crown and Anchor faces
function randFace() {
    return ["crown", "anchor", "heart", "spade", "club", "diamond"]
        [rand(0, 5)];
}

let funds = 50;     // starting conditions 起始條件
let round = 0;

while(funds > 0 && funds < 100) {
    round++;
    console.log(`round ${round}:`); 
    console.log(`\tstarting funds: ${funds}p`);
    // place bets 下注
    let bets = { crown: 0, anchor: 0, heart: 0,
        spade: 0, club: 0, diamond: 0 };
    let totalBet = rand(1, funds);
    if(totalBet === 7) {
        totalBet = funds;
        bets.heart = totalBet;
    } else {
        // distribute total bet
        let remaining = totalBet;
        do {
            let bet = rand(1, remaining);
            let face = randFace();
            bets[face] = bets[face] + bet;
            remaining = remaining - bet;
        } while(remaining > 0)
    }
    funds = funds - totalBet;
    console.log('\tbets: ' +
        Object.keys(bets).map(face => `${face}: ${bets[face]} pence`).join(', ') +
        ` (total: ${totalBet} pence)`);

    // roll dice
    const hand = [];
    for(let roll = 0; roll < 3; roll++) {
        hand.push(randFace());
    }
    console.log(`\thand: ${hand.join(', ')}`);

    // collect winnings
    let winnings = 0;
    for(let die=0; die < hand.length; die++) {
        let face = hand[die];
        if(bets[face] > 0) winnings = winnings + bets[face];
    }
    funds = funds + winnings;
    console.log(`\twinnings: ${winnings}`);
}
console.log(`\tending funds: ${funds}`);
```

## Switch 判斷
從多個條件去做判讀
![](https://i.imgur.com/0CimgvL.png)
![](https://i.imgur.com/bAqKaxh.png)



## While迴圈
  while(判斷){
      若判斷的結果是正確的(true)執行大括號區塊中的程式碼。
      程式碼執行完畢，回到上方while的位置，做第二次判斷。直到判斷結果是錯誤的(false)，才會跳離整個迴圈結構。
  }
  
  小小Debug的寫法
  ![](https://i.imgur.com/rNu7OPm.png)
    
  也可以使用continue
  ![](https://i.imgur.com/wxpsxSz.png)

  還有break
  ![](https://i.imgur.com/OSNPZeZ.png)

  
  ```Example
    <script>
    var n=0;
    while(n<50){
      n++;      
    }
    alert(n);
  </script>
  ```
  ```Example
    <script>
  //如何1加到100?
    var n=0; 
    var sum=0;
    while(n<=100){
      sum=sum+n;
      n=n+1;
    }
    alert(sum);
  </script>
  ```
## While和Do While的差別
![](https://i.imgur.com/BPjYR00.png)


## For迴圈
  for(初始區塊;判斷;迴圈區塊){
      判斷概念同while迴圈。
      請在講解中，注意「初始區塊」與「迴圈區塊」的執行時機。  
  }
  ![](https://i.imgur.com/Zy1i1JU.png)
  
  Let 也可以喔!(ES6)
  ![](https://i.imgur.com/0Yko9dB.png)

  倒著數也是可以的喔
  ![](https://i.imgur.com/2vOiFMo.png)

  
  For、While迴圈可以**相互替代**
  
  ```
    <script>
  //如何1加到100?
    var n=0; 
    var sum=0;
    for(;n<=100;){
      sum=sum+n;
      n=n+1;
    }
    alert(sum);
  </script>
  ```
  該如何使用for迴圈呢?
  ```
    <script>
  //如何1加到100?
    var sum=0;
    for(var i=1;i<=100;i++){
      sum=sum+i;
    }
    alert(sum);
  </script>
  ```
  
  ### 跳著算可不可以啊?
  ![](https://i.imgur.com/jtQ2dRc.png)
  ![](https://i.imgur.com/69iNpC6.png)

  
  ## Break的範例
  強制跳出迴圈
  ![](https://i.imgur.com/VD84Ypz.png)

  ```
    <script>
    var n=0;
    var sum=0;
    while(n<=100){
      
      sum=sum+n
      if (n>=3){
        break;
      }
      n++;
    }
    alert(sum);
  </script>
  ```
  
  ## Continue
  強制進行下一次的迴圈
  ![](https://i.imgur.com/0szd3eR.png)

  以下範例就是跳過4的整數，所以只有顯示75
  
  ```Example
    <script>
    //今天我要示範continue
    var times=0;
    for(var i=0;i<=100;i=i+1){
      if(i%4==0){
        continue;
      }
      times=times+1
    }
    alert(times);
  </script>
  ```
  
 ## 程式碼比較
 判斷式位置不一樣，造成的結果也不一樣
結果5151
 ```
<script>
    //今天我要示範while
var sum=0;
var i=0;
while(i<=100){
  i=i+1;
  sum=sum+i;
}
alert(sum);
</script>
```

結果是5050
```
<script>
var sum=0;
var i=0;
while(i<=100){
  sum=sum+i;
  i=i+1;
}
alert(sum);
</script>
```
## 九九乘法表喔
![](https://i.imgur.com/2dGvCEe.png)

