《自动售货机仿真》
《自動售貨機仿真》實驗報告
一、問題描述
– ① 有一種自動售貨機VM,可售三種商品:可樂(每聽0.25),咖啡(每聽0.25),咖啡(每聽0.30),餐巾紙(每包0.05)。每種商品的示意圖形下方都有一個按鈕。一臺VM中最多能夠容納NC聽可樂、NF聽咖啡、NT包餐巾紙。–②顧客使用VM購買商品時,先從投幣口投入硬幣(共有三種硬幣:0.05)。每種商品的示意圖形下方都有一個按鈕。一臺VM中最多能夠容納NC聽可樂、NF聽咖啡、NT包餐巾紙。–②顧客使用VM購買商品時,先從投幣口投入硬幣(共有三種硬幣:0.05;0.10;0.10;0.25),在投入的硬幣總值達到或超過其欲購商品之價格后,再按下對應商品的按鈕,VM即從出貨口自動吐出一件商品,并從找幣口找零。
– ③ 如果顧客在其投入的硬幣總值沒有達到其欲購商品之價格時就按下了對應商品的按鈕,或者最近一次投幣30秒后既不繼續投幣,也不按下商品按鈕,VM均從找幣口吐出與該顧客已投入的硬幣總值等值的硬幣,但不吐出商品。
– ④ 如果顧客欲購之商品已經售完,則在顧客按下該商品的按鈕后,VM從找幣口吐出與該顧客已投入的硬幣總值等值的硬幣。
– ⑤ 當某種商品還剩NL聽/包時,VM即自動發出短信,將VM的代號和缺貨的商品名稱通知管理人員。管理人員將在時間TM后收到短信,再用時間TS到達VM,并使VM的所有商品存貨都達到最大容納量,取走VM中的硬幣,并留有找零的硬幣:0.05、0.05、0.10、$0.25分別留C5、C10、C25枚。
須仿真的活動及開發結果的行為特征
– 1、開始仿真時,應隨機產生VM中三種商品的存貨量(不能超過其最大容納量)和VM中三種硬幣的數量(分別不小于C5、C10、C25枚)。
– 2、仿真中,應隨機產生前來購物的顧客,隨機產生其欲購買的商品種類,隨機產生顧客的投幣行為(包括③描述的行為),按問題域概述給出的要求進行VM自動售貨活動的仿真。
– 3、NC、NF、NT、NL、C5、C10、C25的值應在運行仿真程序時用命令行給出,或者在開始仿真時從界面輸入。
– 4、實時顯示各種商品的當前存貨量。
– 5、出現情況⑤時,應顯示所發的短信內容,并隨機決定TM和TS的值。在管理人員到達VM之前,應照常進行顧客購物的仿真。管理人員加貨和取款的持續時間可忽略不計。
– 6、仿真開始后,應自動記銷售流水帳。該流水帳的每一行對應著一次售貨,記錄著所售出的商品名稱和售出時間。
– 7、仿真結束時,應自動產生銷售報表。該報表應給出本次模擬過程中:每種商品的銷售總量與價值合計;所有售出商品的價值總計;每種商品的庫存量;模擬開始、結束時各自的庫存金額;管理人員每次加貨的時間、各商品加貨量、取走的硬幣總額。
二、程序設計過程
1. 從實際問題中抽象類
仿真過程關注的事物有:VM,商品(Goods),顧客(Customer),管理員(Administrator)。
程序設計過程中考慮過以下問題:
① 管理員類建立的必要性。若不設計管理員類,而是在VM類中設兩變量TS,TM,VM自動計時,到時間后自動加貨,可實現同樣輸出。從程序外觀上看管理員類的建立與否沒有影響。而考慮到自動加貨并不是VM的本身屬性,而是通過與管理員通信完成的,故建立管理員類。在VM中建立響應管理員加貨的方法,而管理員的內部實現也正是調用了VM的此方法。
② 商品基類建立的必要性。曾考慮過將Goods類設計為虛基類,提供所有商品的共有接口,再從這個虛基類派生處各具體商品,最后運用多態性原理設計實現細節。考慮到這個問題中各商品所不同的地方只是商品名,價格等數據成員不同,類內部方法完全相同。且此程序中一個Goods對象代表一組同種商品,即找不到一個個單獨的商品。在電梯程序中每個乘客有不同的屬性:起始與終止樓層,而這正是程序關系的特征,故建立了一個個具體的乘客對象。此問題中我們關系的只是商品的數量,故沒有一個個單獨的商品對象。
2. 三個類之間的關系
此程序中關鍵是要處理各對象之間的通信。采用以下方法解決:
① VM與顧客之間的通信:顧客有兩種操作,即投幣與按按鈕。在VM中建立響應這兩種操作的函數,顧客類中的兩種操作內部實質是調用VM中的響應函數。只需向顧客的操作函數中傳遞一VM的指針即可實現兩者之間的通信。
② VM與管理員的通信:因VM管理員之間的通信存在時間差,即VM發出的信息需經TM后才能傳遞到管理員,故①中方法不再適用。采用一全局變量(CallAdmTimeLeft)來記錄信息還需多長時間才能到達管理員,其值為-1表示VM為發出請求或上一個請求已被處理,值為0則通知管理員。這樣便可通過主函數完成消息的傳遞。
4.類的設計
1) “Pbulic,h”中聲明定義了各類共享的一些數據類型及運行時需要的一些參數。
類型:
enum Coin{FIVE=5,TEN=10,TWFIVE=25}:硬幣的種類
typedef unsigned int ID:VM編號的類型
typedef int PRICE:價格,現金的類型,單位為美分
typedef int TIME:時間的類型
運行時所需的參數,集中放置方便修改
const int COINKINDS:硬幣種類數目
const int COINMAX:產生顧客時,其擁有的硬幣數目的最大值
const int WAITTIME:顧客兩次操作間最長時間間隔
const int CREATEMAX:一次交易結束后產生下一顧客的最大間隔時間
const int TMMAX:TM的最大值
const int TSMAX=5:TS的最大值
const int THEID:VM的編號
const int RUNTIME:運行的最大時間
2) 商品(Goods)類的設計
變量/函數 成員 作用
私有 string name 標示商品名稱
PRICE price 標示商品價格
int maxNum 售貨機中該商品的最大容量
int leftNum 記錄售貨機中該商品的剩余量
int allSold 記錄該商品的銷售量
Goods(const Goods&) 防止按值傳遞
const Goods& operator=(const Goods&) 防止按值傳遞
公有 Goods(string ,PRICE ,int ,int ) 構造函數
getName() 返回商品名稱
getPrice() 返回商品價格
getLeftNum() 返回剩余數量
getAllSold() 返回銷售量
setMax() 將商品數量沖至最大值
sellOne() 銷售一件商品時應執行的操作
3) 顧客(Customer)類的設計
變量/函數 成員
作用
私有 string goodsWanted 標示所需商品
vector money 投幣順序,建立對象時初始化
PRICE alreadyInsert 已投的金額,用于與商品價格比較,判斷是否按按鈕
PRICE moneyLeft 記錄當前剩余金額
int timeleft 記錄產生下一投幣動作或按按鈕動作還剩的時間
Customer(const Customer&) 防止按值傳遞
const Customer& operator=(const Customer&) 防止按值傳遞
setTimeLeft() 設置產生下一投幣動作或按按鈕動作還剩的時間
setMoneyLeft() 及時更新moneyLeft
公有 Customer(vector) 構造函數
insert(VM*) 處理投幣行為
pressButton(VM*) 處理按按鈕行為
oneSecondPast(VM* ) 程序每運行一秒顧客的更新,返回是否交易結束
Insert函數和pressButton函數的實現主要是調用VM的相應相應函數。
onSecondPast函數實現如下:
4) 管理員(Administrator)類的設計
變量/函數 成員 作用
私有 TIME timeLeft 到達VM剩余的時間,值為-1表示還未收到信息,空閑
VM* pVM 目標VM
公有 Administrator() 構造函數
onCall(VM* theVM) 收到請求時的操作
setMax() 為VM補充貨物
oneSecondPast() 程序每運行一秒管理員的更新
5)VM類的設計
變量/函數 成員 作用
私有 ID id 編號
vector
總結
- 上一篇: gpt linux双系统安装win7系统
- 下一篇: linux 5353端口禁止,系统运维|