物件導向程式設計(ppt 檔, 976 KB)

Download Report

Transcript 物件導向程式設計(ppt 檔, 976 KB)

物件導向程式設計
鄭士康
國立台灣大學
電機工程學系/電信工程研究所/
資訊網路與多媒體研究所
1
綱要
1.
2.
3.
4.
5.
6.
7.
物件導向思維
CRC卡會議
UML類別圖
SRP:單一責任原理
物件導向二十一點模擬程式0.0.0版
物件導向二十一點模擬程式0.0.1版
物件導向二十一點模擬程式0.0.2版
2
綱要
8. 物件導向二十一點模擬程式0.0.3版
9. 物件導向二十一點模擬程式0.0.4版
3
綱要
1.
2.
3.
4.
5.
6.
7.
物件導向思維
CRC卡會議
UML類別圖
SRP:單一責任原理
物件導向二十一點模擬程式0.0.0版
物件導向二十一點模擬程式0.0.1版
物件導向二十一點模擬程式0.0.2版
4
物件導向程式設計
• 利用逐步細分法的函式導向程式設計曾經
風行一時
• 物件和類別的觀念及程式語言普及之後,
有必要採用不同的方式思考,以便更直截
了當的寫出物件和類別的程式,並且充份
發揮物件導向封裝、繼承、多型的特點
5
程式規劃
• 版本規劃 (80-20定律、要事第一、工程方法)
• 測試規劃
• 良好程式設計習慣
– 使用研發日誌,與夥伴合作,漸增式與回合式
發展程式,維持可持續的發展步調,維護原始
碼、註解、重要程式文件
• 測試驅動方法開發
6
物件導向程式設計之引入
• 版本規劃及測試規劃完成,要開始以漸增
及回合方式,進行各個版本的進一步設計
之時
7
物件導向思維
• 什麼是程式要完成的功能?
• 需要那些物件/類別才能完成程式功
能?
• 物件/類別需要那些行為才能合作完
成程式功能?
• 例: Mission Impossible, RPG
8
綱要
1.
2.
3.
4.
5.
6.
7.
物件導向思維
CRC卡會議
UML類別圖
SRP:單一責任原理
物件導向二十一點模擬程式0.0.0版
物件導向二十一點模擬程式0.0.1版
物件導向二十一點模擬程式0.0.2版
9
CRC卡
• Class (類別)、Responsibilities (負責功能)、
Collaborators (合作類別)
• 由Kent Beck與Ward Cunningham發明,用以
教導其同儕程式設計師物件導向的觀念
• 利用CRC卡會議可使初學者更容易了解物件
與類別的意義
10
參考書籍
• N. M. Wilkinson, Using CRC Cards: An Informal
Approach to Object-Oriented Development, New York:
SIGS Books, 1995.
11
練習
• 實際演練二十一點遊戲模擬原型的CRC卡會
議
12
CRC卡會議
定義問題
產生類別
演練場景
整理卡片
13
產生類別
•
•
•
•
腦力激盪
過濾類別
初步建立繼承關係
描述類別
– 寫出類別名稱及定義
– 初步寫出負責功能(Responsibilities)
– 初步寫出資料成員(Attributes)
14
產生類別
腦力激盪
過濾物件/類別
建立繼承關係
描述類別
15
物件/類別之識別
• 流程敘述中的名詞、代名詞、名詞片語
可能需要轉換為物件/類別(CRC卡)
• 流程敘述中的動詞、動詞片語可能需要
轉換為物件/類別的方法(CRC卡)
• 需要相同方法的物件可以歸納出一個類
別(CRC卡)
• 類別之間的關係可以畫UML類別圖表示
• 主程式及類別的方法可以用虛擬碼進一
步描述
16
資料成員與 類別之區分
• 資料成員通常表示類別的狀態變數,而非
單獨之類別或型別
– 撲克牌之花色
– 借書資料之到期日期
• 但資料成員如可操作,且可用藍圖描述,
可能可以構成一個類別,而資料成員變成
一個物件
– 日期
17
必也正名乎
• 物件、類別、狀態、功能之名稱力求精準
• 使用一致命名規範
–
–
–
–
物件、類別、狀態:名詞片語
功能:動詞片語
條件判斷:形容詞片語、判斷句
多字連用,除第一字另外考慮外,各字開頭字
母大寫
– 物件、狀態:第一個字小寫起頭 humanPlayer
– 類別、功能:第一個字大寫起頭 HumanPlayer
18
演練場景
•
•
•
•
•
•
列出場景清單
逐一演練場景
寫下類別負責功能、合作類別、資料成員
先演練簡單場景
複雜場景可能包括其他簡單場景
例外場景押後演練
19
整理卡片
• 刪除沒用到的類別、方法成員、資料成員
• 發現繼承結構
• 繪出類別圖(Class Diagram)
20
CRC卡正面
父類別
負責功能
類別名稱
合作類別
21
CRC卡背面
描述
成員變數
22
類別Card之CRC卡正面
類別名稱: Card
合作類別
負責功能
Deck
知道花色
Hand
知道點數
23
類別Card之CRC卡背面
描述:代表用到的52張撲克牌
成員變數
花色(suit)
點數(rank)
24
類別Deck之CRC卡正面
類別名稱: Deck
合作類別
負責功能
Game
知道剩下的牌
Card
發一張牌
25
類別Deck之CRC卡背面
描述:代表牌疊
成員變數
牌(cards)
26
類別 HumanPlayer之CRC卡正面
類別名稱: HumanPlayer
合作類別
負責功能
Game
存入一張牌
知道玩家狀態
決定是否再要一張牌
傳回手牌總點數
Hand
27
類別HumanPlayer之CRC卡背面
描述:代表人類玩家
成員變數
手牌(hand)
玩家狀態(status)
28
類別Hand之 CRC卡正面
類別名稱: Hand
合作類別
負責功能
Card
知道手中的牌
知道手牌總點數
HumanPlayer
ComputerPlayer
29
類別Hand之 CRC卡背面
描述:代表人類玩家或電腦玩家手中的牌 .
成員變數
牌(cards)
30
類別ComputerPlayer之 CRC卡正面
類別名稱: ComputerPlayer
合作類別
負責功能
Game
存入一張牌
知道玩家狀態
決定是否再要一張牌
傳回手牌總點數
Hand
31
類別 CRC卡背面
描述:代表電腦玩家.
成員變數
手牌(hand)
玩家狀態(status)
32
類別Game之CRC卡正面
類別名稱: Game
合作類別
負責功能
Deck
控制遊戲流程
比較電腦與人類玩家點數
大小
HumanPlayer
ComputerPlayer
33
類別Game之CRC卡背面
描述:代表整個二十一點遊戲.
成員變數
牌疊(deck)
人類玩家(humanPlayer)
電腦玩家(computerPlayer)
34
類別關係圖
HumanPlayer
Game
Deck
Hand
ComputerPlayer
Card
35
綱要
1.
2.
3.
4.
5.
6.
7.
物件導向思維
CRC卡會議
UML類別圖
SRP:單一責任原理
物件導向二十一點模擬程式0.0.0版
物件導向二十一點模擬程式0.0.1版
物件導向二十一點模擬程式0.0.2版
36
UML
• Unified Modeling Language
• 由Booch、Rumbaugh、Jacobson三人所創的
物件導向軟體圖形表示標準
• 做為軟體系統的設計文件,使系統維護者
容易了解修改程式,另一方面則是軟體工
程的工具
– 背後有一套軟體工程架構,但只適合大規模軟
體開發
– 小範圍程式設計,以較簡易具彈性的Agile
Software Development比較實際好用
• 初學者只須了解幾種簡單的圖形,用來了
37
UML繪製工具
• Rational Rose
– 可由UML圖形直接產生程式框架,並能保持程
式與UML圖形的一致性,但價格相當昂貴
• JUDE-Community
– 免費UML圖形繪製軟體
– 自2009年年底,JUDE-Community軟體已不再提
供下載,改提供較進階的astah-Community
http://jude.change-vision.com/jude-web/index.html
38
類別UML符號
39
UML 類別圖( Class Diagram )
40
不同類別間傳送資料
• 類別的成員變數通常設為private,不能任意
擷取
• 有人因此乾脆將所有成員變數宣告為public
,方便取得,卻失去了使用類別封裝的原
意
• 這種狀況,通常可以畫出類別圖,觀察可
能的資料傳送路徑,再於相關類別使用適
當的暫存變數或成員變數和成員函式,進
行接力傳送資料
41
練習
• 以大富翁遊戲模擬為目標,規畫版本,進
行CRC卡會議,產生CRC卡,繪出UML類別
圖
42
astah
43
用astah Community畫類別圖
• File>New
• Diagram>Class Diagram
• 工具列>點選Class符號>在工作區按左
鍵
• 左下角>Base標籤>輸入類別名稱
• 左下角>Attribute標籤>Add按鈕>輸入
資料狀態名稱、型別、可見度
• 左下角>Operation標籤>Add按鈕>輸入
功能函式名稱、傳回值型別、可見度
44
用astah Community畫類別圖
• 工具列>Association符號旁箭頭>選擇所需
Association符號
• 起點類別圖形按左鍵,轉折點按左鍵
• 終點類別圖形連按左鍵兩次
• 按起點、終點類別圖形調整位置
• 或按Shift鍵點選要對齊的圖形>Alignment>
選擇調整方式
• Edit>Copy to Clipboard>BMP, PNG
• File>Save As …
45
綱要
1.
2.
3.
4.
5.
6.
7.
物件導向思維
CRC卡會議
UML類別圖
SRP:單一責任原理
物件導向二十一點模擬程式0.0.0版
物件導向二十一點模擬程式0.0.1版
物件導向二十一點模擬程式0.0.2版
46
單一責任原理
(SRP: Single-Responsibility Principle)
• A class should have only one reason to change
• 若某類別擔負多個責任,某一責任相關的
改變會妨礙該類別其他責任的達成
• 何以不讓Game類別進行某一玩家是否為21
點的計算?
*Robert C. Martin, Agile Software Development: Principles, Patterns, and
Practices, Pearson Education, 2003
47
一個違反SRP的例子
*Robert C. Martin, Agile Software Development: Principles, Patterns, and
Practices, Pearson Education, 2003
48
符合SRP的設計
*Robert C. Martin, Agile Software Development: Principles, Patterns, and
Practices, Pearson Education, 2003
49
綱要
1.
2.
3.
4.
5.
6.
7.
物件導向思維
CRC卡會議
UML類別圖
SRP:單一責任原理
物件導向二十一點模擬程式0.0.0版
物件導向二十一點模擬程式0.0.1版
物件導向二十一點模擬程式0.0.2版
50
BlackJack_0_0_0.Program
using System;
using System.Diagnostics;
namespace BlackJack_0_0_0
{
class Program
{
static void Main(string[] args)
{
Debug.Assert(
BlackJackTest.Scenario_1_OK());
}
}
}
51
混充類別
BlackJack_0_0_0.BlackJackTest
using System;
namespace BlackJack_0_0_0
{
class BlackJackTest
{
public static bool Scenario_1_OK()
{
return true;
}
}
}
52
綱要
1.
2.
3.
4.
5.
6.
7.
物件導向思維
CRC卡會議
UML類別圖
SRP:單一責任原理
物件導向二十一點模擬程式0.0.0版
物件導向二十一點模擬程式0.0.1版
物件導向二十一點模擬程式0.0.2版
53
二十一點遊戲模擬v0.1流程
1. 產生牌疊
2. 電腦(莊家)向玩家(一人)及本身派發一張明
牌
3. 電腦向玩家及本身派發一張明牌
4. 莊家詢問玩家是否加牌, 直至玩家不加牌
或報到
5. 莊家如不足 17點便需加牌直至超過或等於
17點
6. 對未有爆煲或報到的玩家, 比點數大小, 大
者勝, 如莊家爆煲, 玩家勝
54
二十一點遊戲模擬原型之測試規畫:
場景1
玩家
莊家
♠A
♥J
♦10 勝
55
UML 類別圖( Class Diagram )
56
Scenario 1: Sequence Diagram
57
BlackJack_0_0_1.BlackJackTest片段
public static bool Scenario_1_OK()
{
Deck deck = new Deck();
HumanPlayer player = new HumanPlayer();
ComputerPlayer computer = new
ComputerPlayer();
player.SaveACard(deck.DealACard());
computer.SaveACard(deck.DealACard());
player.SaveACard(deck.DealACard());
return (player.IsBlackJack());
}
58
BlackJack_0_0_1.Deck 片段
private Card[] cards;
private int top;
public Deck() {
cards = new Card[3];
cards[0] = new Card(Suit.SPADE, 1);
cards[1] = new Card(Suit.HEART, 11);
cards[2] = new Card(Suit.DIAMOND, 10);
top = 0;
}
public Card DealACard() {
return cards[top++];
}
59
BlackJack_0_0_1.Card 片段
public enum Suit {
CLUB = 0,
DIAMOND = 1,
HEART = 2,
SPADE = 3
}
public struct Card {
public Suit suit;
public int rank;
public Card(Suit suit, int rank) {
this.suit = suit;
this.rank = rank;
}
}
60
BlackJack_0_0_1.HumanPlayer 片段
(1/3)
private Card[] hand = new Card[2];
private int nCards = 0;
public HumanPlayer() {}
public void SaveACard(Card card) {
hand[nCards++] = card;
}
61
BlackJack_0_0_1.HumanPlayer片段
(2/3)
public bool IsBlackJack() {
int point1 = Points( hand[0].rank );
int point2 = Points( hand[1].rank );
bool isBlackJack =
(point1 + point2 == 21);
if (!isBlackJack && point1 == 1) {
point1 = 11;
isBlackJack = (point1 + point2 == 21);
}
62
BlackJack_0_0_1.HumanPlayer片段
(3/3)
if (!isBlackJack && point2 == 1) {
point2 = 11;
isBlackJack = (point1 + point2 == 21);
}
return isBlackJack;
}
private int Points(int rank)
{
int points = rank;
if (rank > 10) points = 10;
return points;
}
63
BlackJack_0_0_1.ComputerPlayer
片段
Card[] hand = new Card[1];
int nCards = 0;
public ComputerPlayer() { }
public void SaveACard(Card card) {
hand[nCards++] = card;
}
64
綱要
1.
2.
3.
4.
5.
6.
7.
物件導向思維
CRC卡會議
UML類別圖
SRP:單一責任原理
物件導向二十一點模擬程式0.0.0版
物件導向二十一點模擬程式0.0.1版
物件導向二十一點模擬程式0.0.2版
65
UML 類別圖
66
BlackJack_0_0_2.BlackJackTest.
Scenario_1_OK 片段
Card[] cards = { new Card(Suit.SPADE, 1),
new Card(Suit.HEART, 11),
new Card(Suit.DIAMOND, 10)
};
Deck deck = new Deck(cards);
HumanPlayer player = new HumanPlayer();
ComputerPlayer computer = new ComputerPlayer();
player.SaveACard(deck.DealACard());
computer.SaveACard(deck.DealACard())
player.SaveACard(deck.DealACard());
return (player.GetStatus() ==
Status.BLACK_JACK &&
computer.GetStatus() == Status.PASS);
67
BlackJack_0_0_2.Deck 片段
private Card[] cards;
private int top = 0;
public Deck(Card[] card) {
int nCards = card.Length;
this.cards = new Card[nCards];
int i;
for (i = 0; i < nCards; ++i) {
this.cards[i] = card[i];
}
}
public Card DealACard() {
return cards[top++];
}
68
BlackJack_0_0_2.Status
public enum Status {
PASS = 0,
BLACK_JACK = 1,
BURST = 2
}
69
BlackJack_0_0_2.HumanPlayer片段
(1/6)
private Card[] hand = new Card[3];
private int nCards;
private Status status;
private int totalPoints;
public HumanPlayer() {
nCards = 0;
}
public void SaveACard(Card card) {
hand[nCards++] = card;
SetStatus();
}
70
BlackJack_0_0_2.HumanPlayer片段
(2/6)
public Status GetStatus() {
return status;
}
public int GetTotalPoints() {
return totalPoints;
}
private int Points(int rank) {
int points = rank;
if (rank > 10) points = 10;
return points;
}
71
BlackJack_0_0_2.HumanPlayer片段
(3/6)
private void SetStatus() {
int[] point = new int[nCards];
int i;
int sum = 0;
for (i = 0; i < nCards; ++i) {
point[i] = Points(hand[i].rank);
sum += point[i];
}
status = JudgeStatus(sum);
totalPoints = sum;
if (status != Status.PASS) return;
bool isWithAce = false;
72
BlackJack_0_0_2.HumanPlayer片段
(4/6)
for (i = 0; i < nCards; ++i) {
if (point[i] == 1) {
isWithAce = true;
break;
}
}
if (isWithAce) {
sum += 10;
if (sum == 21) {
status = Status.BLACK_JACK;
}
73
BlackJack_0_0_2.HumanPlayer片段
(5/6)
if (sum <= 21) {
totalPoints = sum;
}
}
}
74
BlackJack_0_0_2.HumanPlayer片段
(6/6)
private Status JudgeStatus(int sum) {
Status status;
if (sum == 21) {
status = Status.BLACK_JACK;
} else if (sum > 21) {
status = Status.BURST;
} else {
status = Status.PASS;
}
return status;
}
75
綱要
8. 物件導向二十一點模擬程式0.0.3版
9. 物件導向二十一點模擬程式0.0.4版
76
UML 類別圖
77
BlackJack_0_0_3.Program.Main
片段
Debug.Assert(BlackJackTest.DeckRandom_OK(),
"Deck random mode test failed");
Debug.Assert(BlackJackTest.Game_OK(),
"Game test failed");
Console.WriteLine();
Console.WriteLine("21點遊戲開始");
Game game = new Game();
game.Run();
78
BlackJack_0_0_3.BlackJackTest.
DeckRandom_OK 片段 (1/3)
Deck deck = new Deck(123);
Card[] cards = new Card[52];
int i;
for (i = 0; i < 52; ++i) {
cards[i] = deck.DealACard();
}
int[] nSuit = new int[4];
int s;
for (s = 0; s < 4; ++s) {
nSuit[s] = 0;
}
int[] nRank = new int[13];
79
BlackJack_0_0_3.BlackJackTest.
DeckRandom_OK 片段 (2/3)
int r;
for (r = 0; r < 13; ++r) {
nRank[r] = 0;
}
for (i = 0; i < 52; ++i) {
switch (cards[i].suit) {
case Suit.CLUB:
nSuit[0]++;
break;
. . . . . .
}
nRank[cards[i].rank - 1]++;
}
80
BlackJack_0_0_3.BlackJackTest.
DeckRandom_OK 片段 (3/3)
bool suit_OK = true;
for (s = 0; s < 4; s++) {
if (nSuit[s] != 13) {
suit_OK = false;
break;
}
}
bool rank_OK = true;
for (r = 0; r < 13; r++) {
if (nRank[r] != 4) {
rank_OK = false;
break;
}
}
return suit_OK && rank_OK;
81
BlackJack_0_0_3.BlackJackTest.
Game_OK
public static bool Game_OK() {
Console.WriteLine("Game 測試");
Game game = new Game();
game.Run(123);
return true;
}
82
BlackJack_0_0_3.Game 片段
private HumanPlayer player = new HumanPlayer();
private ComputerPlayer computer =
new ComputerPlayer();
public void Run() {
deck = new Deck();
Play();
}
public void Run(int seed) {
deck = new Deck(seed);
Play();
}
83
BlackJack_0_0_3.Game.Play 片段
(1/3)
player.SaveACard(deck.DealACard());
player.Dump();
computer.SaveACard(deck.DealACard());
computer.Dump();
player.SaveACard(deck.DealACard());
player.Dump();
if (IsBlackJackOrBurst()) return;
computer.SaveACard(deck.DealACard());
computer.Dump();
if (IsBlackJackOrBurst()) return;
while (player.GetStatus() == Status.PASS
&& player.WantOneMoreCard()
&& deck.HasMoreCard()) {
84
BlackJack_0_0_3.Game.Play 片段
(2/3)
player.SaveACard(deck.DealACard());
player.Dump();
}
if (IsBlackJackOrBurst()) return;
while ( computer.GetStatus() == Status.PASS &&
computer.WantOneMoreCard() &&
deck.HasMoreCard()) {
computer.SaveACard(deck.DealACard());
computer.Dump();
}
if (IsBlackJackOrBurst()) return;
Console.WriteLine("比大小分勝負");
player.Dump();
computer.Dump();
85
BlackJack_0_0_3.Game.Play 片段
(3/3)
if (IsBlackJackOrBurst()) return;
if (computer.GetTotalPoints() >=
player.GetTotalPoints()) {
Console.WriteLine("電腦勝");
} else {
Console.WriteLine("玩家勝");
}
86
BlackJack_0_0_3.Game.
IsBlackJackOrBurst 片段 (1/2)
bool isBlackJack = false;
if (player.GetStatus() == Status.BLACK_JACK)
{
isBlackJack = true;
Console.WriteLine("玩家 BlackJack!!!");
}
if(computer.GetStatus()== Status.BLACK_JACK)
{
isBlackJack = true;
Console.WriteLine("電腦 BlackJack!!!");
}
bool isBurst = false;
87
BlackJack_0_0_3.Game.
IsBlackJackOrBurst 片段 (2/2)
if (player.GetStatus() == Status.BURST)
{
isBurst = true;
Console.WriteLine("玩家爆!!!");
}
if (computer.GetStatus() == Status.BURST)
{
isBurst = true;
Console.WriteLine("電腦爆!!!");
}
return (isBlackJack || isBurst);
88
BlackJack_0_0_3.Deck 片段
private Card[] cards = new Card[52];
private int top = 0;
public Deck() {
Random rand = new Random();
PrepareDeck(rand);
}
public Deck(int seed) {
Random rand = new Random(seed);
PrepareDeck(rand);
}
89
BlackJack_0_0_3.Deck.
PrepareDeck 片段 (1/2)
bool[] used = new bool[52];
for (i = 0; i < 52; ++i) {
used[i] = false;
}
for (i = 0; i < 52; ++i) {
pos = rand.Next() % 52;
while (used[pos]) {
++pos;
pos = pos % 52;
}
s = pos / 13;
90
BlackJack_0_0_3.Deck.
PrepareDeck 片段 (2/2)
switch (s) {
case 0:
cards[i].suit = Suit.CLUB;
break;
. . . . . .
default:
break;
}
cards[i].rank = pos % 13 + 1;
used[pos] = true;
}
91
BlackJack_0_0_3.Deck.
DealACard & HasMoreCard
public Card DealACard() {
return cards[top++];
}
public bool HasMoreCard() {
return (top < 52);
}
92
BlackJack_0_0_3.HumanPlayer.
WantOneMoreCard
public bool WantOneMoreCard() {
Console.Write("要再一張牌嗎? (y/n) ");
string answer = Console.ReadLine();
return (answer == "Y" || answer == "y");
}
93
BlackJack_0_0_3.HumanPlayer.
Dump 片段
Console.Write("玩家牌: ");
for (i = 0; i < nCards; ++i) {
hand[i].Dump();
Console.Write("\t");
if ((i + 1) % 5 == 0) Console.WriteLine();
}
Console.WriteLine();
Console.WriteLine("玩家總點數: " + totalPoints);
94
BlackJack_0_0_3.ComputerPlayer.
WantOneMoreCard
public bool WantOneMoreCard() {
return (totalPoints < 17);
}
95
綱要
8. 物件導向二十一點模擬程式0.0.3版
9. 物件導向二十一點模擬程式0.0.4版
96
重構(Refactoring)
• 不好的味道(Bad program flavor)
– 重複出現的程式碼
– 不妥的名稱
• 重構
–
–
–
–
擷取方法
重新命名
建立新類別
使用繼承
97
BlackJack_0_0_3重構:
BlackJack_0_0_4
• HumanPlayer與ComputerPlayer中有關
判斷status的函式SetStaus、
JudgeStatus、Points完全相同
• 建立新類別StatusChecker,函式
SetStaus, JudgeStatus, Points改成此一
類別的靜態函式
• SetStatus改名
DetermineStatusAndTotalPoints,並
修改參數
• 將列舉型別Status的宣告移到StatusChecker.cs
98
BlackJack_0_0_4.Status
public enum Status {
PASS = 0,
BLACK_JACK = 1,
BURST = 2
}
99
BlackJack_0_0_4.StatusChecker.
DetermineStatusAndTotalPoints (1/2)
public static void DetermineStatusAndTotalPoints(
Card[] hand, int nCards, out Status status,
out int totalPoints) {
int[] point = new int[nCards];
int sum = 0;
for (i = 0; i < nCards; ++i) {
point[i] = Points(hand[i].rank);
sum += point[i];
}
status = JudgeStatus(sum);
totalPoints = sum;
if (status != Status.PASS) return;
bool isWithAce = false;
100
BlackJack_0_0_4.StatusChecker.
DetermineStatusAndTotalPoints (2/2)
for (i = 0; i < nCards; ++i) {
if (point[i] == 1) {
isWithAce = true;
break;
}
}
if (isWithAce) {
sum += 10;
if (sum == 21) {
status = Status.BLACK_JACK; }
if (sum <= 21) {
totalPoints = sum; }
}
}
101
BlackJack_0_0_4.HumanPlayer.
SaveACard
public void SaveACard(Card card) {
hand[nCards++] = card;
StatusChecker.
DetermineStatusAndTotalPoints(
hand, nCards, out status,
out totalPoints);
}
102