2011年7月7日 星期四

[學習筆記]用Matlab連結(呼叫)Outlook來寄信

  這個暑假我們研究所要一連舉辦兩個學術性研討會,而自己因接下了其中一場學術組組長一職,這學期變得無敵的忙碌,當然為了節省自己繁雜業務所耗費的時間,有許多工作都是自己撰寫程式來完成的(ex. 整理稿件清單、稿件更新狀態、檢查有無重覆投稿…)。
  因為接下來就要寄發一些信件通知給投稿的作者們,但我們大會網站後台系統當初廠商在設計的時候,寄發信件的格式已經被他們寫死了無法更改,如果要他們改程式的話,勢必要再花一些$$及時間,$$可能不是什麼問題,但時間可是很緊迫的,所以我便開始著手完成這個批次寄信的程式,沒想到不會很難,只花了不到半天就完成了主要寄信的code (大部分時間都是在查函式的說明文件,真正寫code應該不用30分鐘)。

程式語言:Matlab
Outlook版本:2007
簡單程式範例:


line1: 啟動Outlook ActiveX Server
line2: 新增一個郵件物件
line3: 郵件標題
line4: 收件人email
line5: 設定郵件為HTML格式
line6: 郵件內容,可以是HTML編碼
lint7: 寄出,改成 mail.Display就會出現信件的視窗,可以手動按下「傳送」來寄出。改成mail.Save就會將郵件存在草稿匣內。

2011年6月23日 星期四

智慧型手機/平板電腦於臨床醫療上的應用

 這是我在學校修的一門課(臨床醫療概論)所交的期末報告書

題目:智慧型手機/平板電腦於臨床醫療上的應用


一、發展歷史
定義

「智慧型手機」(Smartphone)並不是指手機本身具有「智慧」,而是指手機本身可以如電腦一般任意地新增或移除應用軟體且具備有硬體擴充的能力。而智慧型手機早期是由「功能手機」(Future phone)發展而來的,而功能手機並無法隨意的新增移除應用程式,但隨著演進後來支援安裝以Java所開發出來的應用程式,但Java程式在功能手機上的執行效能及軟體開發友好性都比後來出現的智慧型手機有一段很大的差距,因此智慧型手機逐漸的取代了功能手機的市場。
「平板電腦」(Tablet personal computer)早期是改良現有的筆記型電腦,將其螢幕改為觸碰式螢幕,使用者可以選擇以觸碰方式來取代滑鼠與鍵盤的操作,獲得許多商務人士的喜愛,但並不普及。但直到蘋果電腦的iPad2010年上市後,所使用的iOS作業系統 (iPhone智慧型手機的作業系統)使操作更加容易,且支援許多人性化的多點觸碰手勢操作,因此受到許多民眾的喜愛,進而引起平板電腦的熱潮,許多大廠紛紛開始發表各自的平板電腦,市場預估2012年平板電腦的銷售量就會超越小筆電,在資訊界稱此為「後電腦時代」(Post-PC Era)
目前智慧型手機系統的建置方式主要可分為2種:
1.   專為智慧型手機所開發的系統平台:如NokiaSymbian作業系統、微軟的Windows Mobile作業系統、蘋果電腦的iOS作業系統、GoogleAndroid作業系統等。
2. 使用傳統「掌上型電腦」(PDA)系統平台再加入手機通訊功能:如微軟的Windows Mobile Pocket PC Phone系列及Palm作業系統。

常見智慧型手機作業系統
1.      iOS:原名為iPhone OS,為蘋果電腦出售的iPhoneiPod TouchiPad所專屬的作業系統,由於並未開放作業系統原始碼,所以其他硬體開發商並無法使用此作業系統來開發智慧型手機產品,但可以藉由裝置的耳機孔及底部的插槽來開發擴充的硬體配件。於軟體開發上,應用程式需從蘋果的App Store購買及下載,目前支援第3方軟體的開發,但需經由蘋果的審核後放上App Store中才完成軟體發行。
2.      Android:由Google所開發的智慧型手機平台,是以Linux為基礎的開放原始碼作業系統,由於20102Linux的核心開發者將Android從名單中去除,此後Android的核心開發由Google自行接手。由於其作業系統的開源性,因此其他手機硬體開發商可以輕易的開發出Android作業系統的智慧型手機進行販售。而在軟體開發上也較iOS更為開放,審查制度較為寬鬆,其專屬的Android Market可提供使用者下載及購買應用程式。
3.      Palm OS/WebOSPalm OS原為Palm公司所開發的掌上型電腦作業系統,但2007年後停止開發,於2010Palm被惠普(HP)公司收購後Palm OS改名為WebOS,進而將開發重點放置於手機與平板作業系統中。
4.      Windows Mobile:微軟所出品的windows mobile系列早期在掌上型電腦與智慧型手機的作業系統擁有很高的市佔率,但由於iOSAndroid這兩大競爭對手的出現,逐漸喪失於智慧型手機作業系統的地位,近期微軟正積極開發全新的智慧型手機作業系統Windows Phone 7,也許有機會扳回目前的劣勢,但其應用程式開發數量還是差iOSAndroid一大截。
5.      Symbian:為許多手機大廠共同成立的Symbian公司所開發的手機作業系統,曾經一度十分熱門,2008年被Nokia收購後轉為以開放原始碼方式釋出,但由於iPhoneGoogle Android的出現,對於Symbian造成極大的威脅,市佔率不斷的下滑,因此於20112Nokia正式宣布與微軟合作,共同開發Windows Phone 7作業系統。
6.      BlackBerry OS:開發商為Research in Motion,在台灣稱作「黑莓機」,是專為商務人士所打造的智慧型手機作業系統,因此在郵件處理的功能上十分強大。屬封閉式系統,但支援第3方軟體的開發。

目前市面上常見的智慧型手機及平板電腦
1.      手機
iPhone系列:iOS作業系統。
HTC Sensation/Desire HDGoogle Android作業系統加上自行開發的HTC Sense功能。
HTC HD7/7 MozartWindows Phone 7作業系統
Nokia XpressMusic系列:Symbian作業系統。
BlackBerryBlackBerry作業系統

2.      平版電腦
iPad系列:iOS作業系統。
HTC FlyerGoogle Android作業系統。
ASUS Transformer (變形平板)/ Motorola XoomGoogle Android 3.0作業系統(專為平板電腦開發的作業系統)



二、臨床應用說明
由於智慧型手機具有方便可攜、可使用Wifi或手機網路上網、可任意安裝/移除應用程式等便利性。再加上硬體設備的進步,某些智慧型手機的運行速度與計算能力已經可與一般桌上型電腦比擬。因此,許多開發廠商著手開發一些臨床上可應用的智慧型手機軟硬體,目前國外已經有許多醫院已經開始於臨床上使用。

軟體
1.      電子書:由於平板電腦的上市,因此醫療相關的電子書籍也開始跟著販售,有些電子書更加入應用程式界面,讓資料更好查詢及閱讀,甚至加入許多影音資料。如解剖、生理、藥典、手術等相關電子書現在皆可購買取得,方便醫療人員的進行資料查詢、教學以及對患者進行衛教。
2.      病歷查閱:由於可以利用手機網路上網的關係,醫療人員可隨時隨地使用智慧型手機透過手機網路或者是無線網路與醫院所建立雲端資料庫進行連結,取得病人的病歷及相關的檢查結果,不用再特地跑到護理站或是診間查詢,在國外許多醫院裡,醫護人員人手一台iPad已經是十分普遍的現象了。

硬體
1.      血壓機:iHealth血壓機模組是目前已開始販售的iPhone擴充套件,定價為99.95美元,血壓機所使用的應用程式則可以免費在App Store中下載並安裝。與一般電子血壓機最大的差別在於,應用程式可以在iPhone中建立使用者個人的資料庫,詳細的紀錄下血壓量測的數據以及時間,並即時利用網路將量測結果以Email方式寄出,讓使用者的醫師或家人可以協助進行血壓的監控。而每筆血壓紀錄並不會佔用系統太大的空間,所以可以儲存大量的血壓量測紀錄,使用者得以十分輕易的追綜與查詢自己的血壓狀況。此外,軟體的操作界面也較一般電子血壓計來得更簡單與美觀。因為使用iPhone作為血壓機的主機,因此血壓機所佔用的空間會比一般電子血壓機還要小。

2.      血糖機:iBGStarsanofi aventid公司所開發的iPhone血糖機擴充套件,預估售價約為80美元。因為使用iPhone作為軟體界面的平台,因此整個組件較一般血糖機還要小,便於攜帶。當然,所有的血糖資訊也都會儲存在iPhone之中方便日後進行管理。另外Johnson & Johnson公司也有開發可與iPhone連結的血糖機,其軟體功能更加豐富,除了可以紀錄下使用者所量測的血糖值外,還可以結合使用者的飲食紀錄提供給使用者一些建議。

3.      酒測儀:這款由David Steele所開發的iBreath酒精濃度測試iPhone/iPod擴充套件,目前售價為39美元,其娛樂性質可能更大於他醫療上的應用。與好友聚會,小酌幾杯後,想知道自己身體裡的酒精濃度是否已被代謝至標準值之下?開車回家時就不用怕被警察伯伯抓到派出所,難怪被號稱為史上最好的iPod擴充套件。此外,此套件還有另外一個功能,就是可以將iPhone/iPod搖身一變身成為FM頻道發射器,使用者就可以透過車上的收音機接收到iPhone/iPod裡所撥放的音樂,用汽車裡的音響聽個過癮。

4.      心電圖量測:最早是由AliveCor2011年國際消費電子展(CES)所發表,目前只有原型機,並未開始販售(影片:http://www.youtube.com/watch?v=d5Pip8qLfPs)。他們將感應器作成像手機保護殼一樣,因此裝上時就跟一般iPhone沒什麼差別,而感應裝置設置於背後的兩片金屬板,在展示影片中,顯示出此裝置靈敏度十分的高,只要將兩隻手的手指分別按壓在兩片金屬板上,甚至將裝置直接接觸身體(如胸口),在螢幕上即可顯示出十分清晰心電圖訊號。


5.      遠端監控心肺復健患者:這是由Worringham等人於2011年所發表的系統,目前仍然在開發中,所以並未上市,他們是利用有GPS接收器功能的智慧型手機(也可以使用的獨立的GPS接收器,再利用藍牙將訊號傳至手機),將患者身上ECG接收器的訊號利用藍牙傳至手機,再藉由手機網路將所有資訊傳送至雲端的伺服器中。這樣一來,醫護人員就可以利用遠端監控的方式觀察患者的身體狀態及其所在位置,當患者身體有異狀時,可以使用手機與患者聯絡,或者可以藉由GPS訊號的位置,即時到達給予協助。



三、優缺點分析
優點
1.      作業系統穩定性、開機速度:由於智慧型手機的作業系統相較於桌上/筆記型電腦的作業系統(WindowsMac OS)更為精簡,因此整體的穩定性較高且開機速度較快。進而再比較目前兩大智慧型手機作業系統iOSGoogle AndroidiOS由於對於第3方開發的應用程式有較嚴格的審核,所以系統比後者還要更加穩定,然而Google Android因為系統過於開放,對於應用程式的審核也較為寬鬆,比較容易產生bug造成系統的不穩,因此目前醫療儀器開發廠商多採用iOS系列的智慧型手機及平板電腦進行週邊的開發。

2.      軟、硬體容易開發:在智慧型手機上開發醫療儀器擴充最大的好處是,可以省去為儀器開發作業系統及核心的時間,直接使用智慧型手機現有系統及核心就可以了,因此可以把開發的重心放置在硬體設計與使用者操作界面上(軟體),讓整個儀器的開發更為簡單、快速,而界面也可以更為美觀。

3.      可移動性、無線傳輸資料、雲端同步資料:可移動性這是智慧型手機及平板電腦最大的優勢,輕巧容易攜帶且資料處理能力也能與一般電腦平起平坐。加上手機網路的便利性,甚至所有資料都可以透過網路雲端來進行存取,可以十分輕易地就可以與其他人分享資訊及備份資料。

4.      操作容易:智慧型手機使用觸碰的操作方式來取代傳統的鍵盤與滑鼠輸入方法,更加入許多手勢的操作(需支援多點觸碰的機型),讓整體操作更加直觀且簡單易學,。

5.      省電:由於硬體科技及電池技術的進步,再加上較精簡作業系統與運算核心設計,智慧型手機與平板電腦的處理器核心及週邊的硬體都可以作到比筆記型電腦還要更低的功耗,因此電池的續航力大大的提升,許多機種甚至都可以持續使用10幾個小時不用充電。

6.      售價便宜:由於智慧型手機與平板電腦逐漸成為市場的主流,因此售價相較於桌上型電腦或是筆記型電腦還要來得低許多,但其功能已經足以與桌電與筆電匹敵。

缺點
1.      軟體開發跨平台整合困難度高:由於目前兩大智慧型手機作業系統iOSGoogle Android軟體開發所主要使用的程式語言是不同的(Object C vs. Java),相同應用程式想要跨平台使用幾乎是要重新撰寫程式碼才行,所以通常開發初期只會選擇其中一個來進行(大部分都是先從iOS作業系統開始),若有不錯的成效才可能進行另一個平台的移植。因此,除非有一個很強大的開發團隊,不然市場的餅就很難一開始就做大。

2.      網路安全性:因為智慧型手機的儲存空間與運算能力還是有其限制,因此許多應用程式會使用到雲端運算及雲端資料儲存的技術,若稍不注意,資料有可能就會被駭客所竊取。尤其所開發的又是醫療相關的產品,應更加重視個人隱私的部分。

四、市場分析
分析報告
1.      作業系統市佔率:根據Millennial Media20115月的分析報告,全球智慧型手機已達到68%的市佔率穩居龍頭,而在智慧型手機作業系統則是由Google Android53%取得市場的主導地位,次者為Apple iOS28%,而RIM黑莓機作業系統位居第三,市場呈現三強鼎立的局面。

2.      應用程式數量
統計日期:2011/6/23
供應商
軟體總數
免費軟體比例
醫療相關App
App Store (蘋果)
413,749
38.48%
17,148 (4.14%)
Android Market (Google)
400,000
62.4%
9,056
WP7 Applist (微軟)
23,450
51%
3%

市場預測
1.      作業系統市佔率:根據IDCGartner所提出的市場預測,2015年智慧型手機作業系統的市佔率仍以Google Android穩居龍頭,而Windows Phone將後來居上取代Symbian

2.      應用程式數量:research2guidance根據今年5月份的數據預估Android Market的應用程式數量會在20118月超越蘋果的App Store







五、參考文獻
3.      Kiser K. 25 ways to use your smartphone. Physicians share their favorite uses and apps. Minn Med. 2011, 94(4):22-9
4.      Dala-Ali BM, Lloyd MA, Al-Abed Y. The uses of the iPhone for surgeons. Surgeon. 2011, 9(1):44-8
9.      Worringham C, Rojek A, Stewart I. Development and feasibility of a smartphone, ECG and GPS based system for remotely monitoring exercise in cardiac rehabilitation. PLoS One. 2011, 9;6(2):e14669

2011年5月25日 星期三

[學習筆記]使用JavaScript 新增/修改/刪除 MS Access資料庫

利用 JavaScript 來連接資料庫在內行人看來可能會覺得安全性不夠,因為等於資訊完全被看光光。但如果只是想撰寫一個單機使用的資料庫處理網頁界面,JavaScript就方便許多,至少不用為了資料庫處理而架一個伺服器。使用的語法也不會很難,但缺點就是目前只相容於IE瀏覽器,若使用firefox或chrome就無法使用了(囧)。

主要會使用到2個ActiveX物件:ADODB.Connection跟ADODB.Recordset
前面的比較簡單,就是跟資料庫連線所使用的,使用到的Connection String的語法是參考這裡
基本上這個物件只會使用到Open跟Close這兩個方法。
假設資料庫檔案在 c:\test.accdb (Access 2007的資料庫格式)

應該會看見彃跳視窗出現「連線成功」的訊息。

ADODB.Recordset這個物件使用到的方法較多,而且也會使用到SQL語法來操作,但整體上來說也不會太難。
假設test.accdb這個資料庫裡面有一個叫做demo的表格 (表格建立在Access內完成)
表格內有3個項目key(自動編號)、product (產品名稱)、price (售價)
若要新增一筆資料產品名稱為iphone4,售價為499


若要修改產品iphone4的售價為599


若要將產品iphone4從資料庫中移除

2011年5月22日 星期日

[學習筆記]Chrome與IE的JavaScript除錯工具

開啟方法
IE: 快速鍵 F12 (工具->開發者工具)
Chrome: 快速鍵 Ctrl+Shift+I (工具->開發人員工具)
Firefox: 快速鍵 Ctrl+Shift+K (工具->網頁主控台)

常用程式碼
console.log是個很好用的工具,可以取代alert那煩人的彈跳視窗,讓程式運行的更順暢 ^^
訊息將會列印在開發工具視窗中
例:

2011年4月27日 星期三

[程試分享]雲.蝦米 (雲端無蝦米輸入法)

雲.蝦米
雲端無蝦米輸入法 for Chrome Extensions

目前版本:0.0.3.r1
狀態:尚在開發中,但已經可以使用了^^
因為想要嘗試寫寫看chrome的擴充功能程式,加上本身也是無蝦米輸入法的使用者,所以就以此為題材。雲端的字碼對照表格是建立在Google App Engine的伺服器中,字碼對照表沒有使用無蝦米官方的表格,而是使用我自己修改後的表格並以資料庫的形式來分析、讀取,所以目前僅有基本的中文輸入,並不支援外字。
暫時只能在Chrome瀏覽器的環境下執行
安裝擴充功能

使用說明
Google Code頁面



執行畫面
執行畫面

測試報告:
Google: ok!
GMail: ok!
Facebook: ok!
imo: ok!
Blogger: ok!
Notepad.cc: ok!
Google文件(試算表): ok! 但很lag...
Google文件(文件): 無法使用! 囧!

2011年4月21日 星期四

[程式分享] 數獨 Part. 3:遊戲操作界面 (終端機)

SudokuGen.h與SudokuGen.cpp的程式碼
DigSudoku.h與DigSudoku.cpp的程式碼
SolveSudoku.h與SolveSudoku.cpp的程式碼

開發環境: Windows XP 32bit
編輯器: Code Blocks
Compiler: GNU GCC compiler (MinGW)

遊戲界面所使用的Library: pdcurses

若是在Linux下compile的話,請安裝ncurses,並將 line 4 改成
#include "ncurses.h"

若是在Cygwin下compile的話,請安裝ncurses,並將 line 4改成
#include "ncurses/ncurses.h"


main.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263

#include "SudokuGen.h"
#include "DigSudoku.h"
#include "SolveSudoku.h"
#include "curses.h" // pdcurses library: 用來產生遊戲界面 (需另外安裝)
#include <vector>
using namespace std;

void print_edge(); //印出棋盤框
void print_result(vector<int >,bool [][9]); //印出答案

int main()
{
    int Ans=0;
    int i,j; //迴圈用變數
    int ch;  //紀錄按鍵
    int startx = 0, starty = 0; //游標起始位置
    int pos[9][9][2]; //棋盤的loacl座標所對映的global座標
    bool check[9][9]; //紀錄每個棋盤格是屬於已知(1)或是未知(0)
    bool game_term = false; //遊戲執行狀態(true:結束)
    int count[9]; // 紀錄1-9所有數字的個數
    for (i=0;i<9;i++)
    {
        count[i] = 0;
    }
    vector <int> Ans_board(81); //答案
    vector <int> board(81); //題目
//====================初始化視窗============================
    initscr();
    start_color();
    init_pair(1,COLOR_GREEN,COLOR_BLACK);
    init_pair(2,COLOR_YELLOW,COLOR_BLACK);
    cbreak();
    noecho();
    keypad(stdscr,TRUE);
//========================產生題目===========================
    printw("Initialzing...");
    refresh();
    SudokuGen Exam1;
    while(Ans!=1)
    {
        Exam1.generator(); //產生題目
        DigSudoku DigExam1(Exam1.get_board(),35); // 挖洞出題
        SolveSudoku SolExam1(DigExam1.get_board(),0); // 解題
        Ans = SolExam1.getAns(); // 取得題目總共有多少個解
        if (Ans==1 && Exam1.get_board()==SolExam1.get_board())
        {
            //出題條件成立
            board = DigExam1.get_board(); //題目
            Ans_board = Exam1.get_board(); //解答
            break;
        }
    }
    printw(" >> Complete!");
//====================顯示作者資訊============================
    attron(A_BOLD);
    attron(COLOR_PAIR(2));
    mvprintw(0,45,"Author: Herman Liang (2011-03)");
    attroff(COLOR_PAIR(2));
    attroff(A_BOLD);
    refresh();
//====================產生棋盤框架=============================
    print_edge();
//====================將題目寫入棋盤===========================
    for (i=0;i<9;i++)
        for (j=0;j<9;j++)
        {
            if (board[i*9+j]!=0)
            {
                attron(A_BOLD);
                attron(COLOR_PAIR(1));
                mvprintw(i+5+i/3,(j+j/3)*2+5,"%d",board[i*9+j]);
                attroff(COLOR_PAIR(1));
                attroff(A_BOLD);
                check[i][j] = true;
                ++count[board[i*9+j]-1];
            }
            else{check[i][j] = false;}
//------------紀錄棋盤的loacl座標所對映的global座標--------------
            pos[i][j][0] = i+5+i/3;
            pos[i][j][1] = (j+j/3)*2+5;
        }
//====================產生剩餘數字個數計數器=========================
    for (i=5;i<14;i++)
    {
        mvprintw(i,35,"%d: ",i-4);
        for (j=0;j<9-count[i-5];j++)
        {
            mvprintw(i,j+38,"*");
        }
    }
    refresh();
//====================移動指標至起始位置==========================
    move(pos[starty][startx][0],pos[starty][startx][1]);
//====================開始監視鍵盤動作============================
//--------------------迴圈結束條件:q鍵---------------------------
    while((ch = getch()) != 'q' && !game_term)
    {
        switch(ch)
        {
            case KEY_LEFT:
                mvaddstr(1,10,"Left ");
                mvprintw(22,0,"        ");
                --startx;
                break;
            case KEY_RIGHT:
                mvaddstr(1,10,"Right");
                mvprintw(22,0,"        ");
                ++startx;
                break;
            case KEY_UP:
                mvaddstr(1,10,"Up   ");
                mvprintw(22,0,"        ");
                --starty;
                break;
            case KEY_DOWN:
                mvaddstr(1,10,"Down ");
                mvprintw(22,0,"        ");
                ++starty;
                break;
            case 's': //檢查答案是否正確
                if (board == Ans_board)
                {
                    mvprintw(22,2,"Success!");
                    print_result(Ans_board,check);
                    game_term = true;
                    break;
                }
                else
                {
                    mvprintw(22,2,"Fail!");
                    break;
                }
            case 'r': //顯示結果
                print_result(Ans_board,check);
            default:
                mvprintw(1,10,"%c    ",ch);
                mvprintw(22,2,"        ");
//------------------該格子為空白且輸入數字時產生的動作-----------------
                if (check[starty][startx]==0)
                {
                    if (ch>=48 && ch<=57) //數字0-9區間(48-57)
                    {
                        if (ch==48) //輸入數字為0
                        {
                            if (board[starty*9+startx]!=0)
                            {
                                --count[board[starty*9+startx]-1];
                            }
                            board[starty*9+startx] = 0;
                            mvprintw(pos[starty][startx][0],pos[starty][startx][1]," ");
                        }
                        else //輸入數字為1-9
                        {
                            int ch_int = ch-48;
                            if (board[starty*9+startx]!=0)
                            {
                                --count[board[starty*9+startx]-1];
                            }
                            ++count[ch_int-1];
                            board[starty*9+startx] = ch_int;
                            mvprintw(pos[starty][startx][0],pos[starty][startx][1],"%c",ch);
                        }
                        for (i=5;i<14;i++) //重新整理剩餘數字個數計數器
                        {
                            mvprintw(i,38,"         ");
                            for (j=0;j<9-count[i-5];j++)
                            {
                                mvprintw(i,j+38,"*");
                            }
                            if (count[i-5]>9)
                            {
                                mvprintw(i,38,"%d",9-count[i-5]);
                            }
                        }
                    }
                }
        }
//-----------------------游標超出邊界的處理----------------------------
        while(startx < 0)
        {
            startx += 9;
        }
        while(startx >= 9)
        {
            startx -= 9;
        }
        while(starty < 0)
        {
            starty += 9;
        }
        while(starty >= 9)
        {
            starty -= 9;
        }
// ----------------------顯示目前座標位置------------------------------------
        mvprintw(1,16,"(%d,%d)  %d",starty,startx,check[starty][startx]);
// -------------------更新座標座置(若有按「上下左右」)-----------------------
        move(pos[starty][startx][0],pos[starty][startx][1]);
        refresh();
    }
// -------------------------結束視窗-----------------------------------------
    endwin();
 return 0;
}
// 印出棋盤框
void print_edge()
{
    int i,j;

    for (i=0;i<4;i++)
        for (j=0;j<9;j++)
        {
            mvprintw(i*4+4,(j+j/3)*2+4,"--");
        }

    for (i=0;i<9;i++)
        for (j=0;j<4;j++)
        {
         mvprintw(i+5+i/3,j*8+3,"|");
        }
    mvprintw(4,3,"/");
    mvprintw(4,26,"\\");
    mvprintw(16,3,"\\");
    mvprintw(16,26,"/");


    for (i=0;i<4;i++)
        for (j=0;j<9;j++)
        {
            mvprintw(i*4+4,(j+j/3)*2+54,"--");
        }

    for (i=0;i<9;i++)
        for (j=0;j<4;j++)
        {
         mvprintw(i+5+i/3,j*8+53,"|");
        }
    mvprintw(4,53,"/");
    mvprintw(4,76,"\\");
    mvprintw(16,53,"\\");
    mvprintw(16,76,"/");

    mvprintw(20,2,"s:Solve    0:Clear Bolck    r:See Result    q:Quit");
}
// 印出答案
void print_result(vector<int > board,bool check[][9])
{
    int i,j;
    for (i=0;i<9;i++)
        for (j=0;j<9;j++)
        {
            if (check[i][j]==true)
            {
                attron(A_BOLD);
                attron(COLOR_PAIR(1));
                mvprintw(i+5+i/3,(j+j/3)*2+55,"%d",board[i*9+j]);
                attroff(COLOR_PAIR(1));
                attroff(A_BOLD);
            }
            else{mvprintw(i+5+i/3,(j+j/3)*2+55,"%d",board[i*9+j]);}

        }
}