孫瑜
摘 要 為了提高程序設(shè)計課程的教學(xué)效果,通過游戲類趣味問題驅(qū)動來引發(fā)學(xué)習(xí)興趣,借助程序設(shè)計的知識載體,學(xué)習(xí)和掌握基本問題的求解過程和基本思路;以達到在解決問題的實踐中訓(xùn)練和培養(yǎng)觀察能力、分析解決問題的實踐能力。
關(guān)鍵詞 教學(xué)設(shè)計 猜數(shù)字游戲 程序設(shè)計 實踐
中圖分類號:G633 文獻標識碼:A
0序言
計算機程序設(shè)計語言課程如 C、C++語言課程,是一門受眾面廣、實用性強的課程。在多年的C++教學(xué)中,不乏學(xué)生們對C++編程難學(xué)、枯燥的抱怨。程序設(shè)計課程是“編”出來的,學(xué)生要花大量時間在上機實驗中去編程序,僅僅在面授課中講解是遠遠不夠的。如何在上機實驗中激發(fā)學(xué)生的興趣,調(diào)動起學(xué)生的學(xué)習(xí)積極性,對于學(xué)好C++語言這樣實踐性強的課程是十分重要的。為了達到更好的學(xué)習(xí)效果,需要讓學(xué)生主動學(xué)習(xí),以學(xué)生為主體,以激發(fā)學(xué)生的興趣為目標,強調(diào)實踐和思考的教學(xué)理念。更多的是通過學(xué)生自主閱讀、實驗、程序編寫、調(diào)試等環(huán)節(jié)達到學(xué)習(xí)目的。
1問題引入
為了循序漸進地引入教學(xué)內(nèi)容,同時考慮到對不同學(xué)生進行因材施教,設(shè)計具有游戲趣味的猜數(shù)字問題,根據(jù)難易程度分為如下三個等級:
(1)問題1(用戶猜測100以內(nèi)隨機整數(shù)):電腦隨機產(chǎn)生一個1-100之間的隨機數(shù),讓用戶猜測,電腦提示用戶猜大了、猜小了還是猜對了,根據(jù)提示,若沒猜對,用戶繼續(xù)猜測下一個數(shù)字,直到猜對為止。要求猜測次數(shù)不超過10次。
(2)問題2(用戶猜測電腦產(chǎn)生的4位整數(shù)):電腦隨機產(chǎn)生一個各位互不重復(fù)的4位整數(shù),請用戶猜測一個數(shù)字,電腦反饋信息為xAyB,以字母A表示用戶猜對了x個僅數(shù)值正確,位置不正確的數(shù)字,以字母B表示y個數(shù)值和位置都正確的數(shù)字,例如:如果系統(tǒng)生成的數(shù)字為2794,而玩家輸入的數(shù)字為1234,則反饋信息為 2A1B。根據(jù)反饋,用戶繼續(xù)猜測下一個數(shù)字,如果反饋信息為4A4B則意味著玩家猜出了全部的4個數(shù)字而獲勝。
(3)問題3(電腦猜測用戶想的4位整數(shù)):用戶想一個各位互不重復(fù)的4位整數(shù),請電腦猜測一個數(shù)字,用戶反饋信息xAyB,以字母A表示用戶猜對了x個僅數(shù)值正確,位置不正確的數(shù)字,以字母B表示y個數(shù)值和位置都正確的數(shù)字,例如:如果系統(tǒng)生成的數(shù)字為2794,而玩家輸入的數(shù)字為1234,則反饋信息為 2A1B。根據(jù)反饋,電腦繼續(xù)猜測下一個數(shù)字,如果反饋信息為4A4B則意味著電腦猜出了全部的4個數(shù)字而獲勝。要求電腦猜測的次數(shù)不超過10次。
2教學(xué)設(shè)計
為了達到更好的教學(xué)效果,讓學(xué)生參與學(xué)習(xí)、主動學(xué)習(xí),增強學(xué)習(xí)興趣,對不同難度的問題,進行不同的教學(xué)過程設(shè)計。
問題1:提出問題,程序演示,分析問題,任務(wù)分解,流程設(shè)計,代碼設(shè)計,代碼調(diào)試。
問題2:提出問題,程序演示,分析問題,課下自行代碼編寫,代碼調(diào)試。
問題3:提出問題,程序演示,關(guān)鍵任務(wù)思路分析,數(shù)據(jù)結(jié)構(gòu)設(shè)計,課下代碼編寫、調(diào)試。
2.1 問題分析
2.1.1問題1的任務(wù)分解
任務(wù)1.1 產(chǎn)生一個100以內(nèi)的隨機數(shù);任務(wù)1.2 用戶猜測一個數(shù)字; 任務(wù)1.3 判斷猜測的正確性,并給出提示;任務(wù)1.4 若沒猜對,繼續(xù)轉(zhuǎn)任務(wù)12。若猜對了,或者猜測次數(shù)超過10次,結(jié)束程序。
2.1.2問題2的任務(wù)分解
任務(wù)2.1 產(chǎn)生一個無重復(fù)四位數(shù);任務(wù)2.2 用戶猜測一個數(shù)字;
任務(wù)2.3 分析猜測結(jié)果,給出提示;進一步細分難點任務(wù)。
任務(wù)2.3.1 將四位數(shù)的各位分離,分別分離產(chǎn)生的答案數(shù)字和用戶猜測數(shù)字的各位數(shù)字;
任務(wù)2.3.2 比較答案和猜測的數(shù)字,得出猜測結(jié)果xAyB;
任務(wù)2.4 若猜測正確或猜測次數(shù)>10,結(jié)束猜測;否則,轉(zhuǎn)任務(wù)22;任務(wù)2.5 輸出猜測結(jié)果。
2.1.3問題3的任務(wù)分解
任務(wù)3.1 用戶默想一個無重復(fù)四位數(shù);任務(wù)3.2 程序產(chǎn)生一個候選猜測數(shù)字;任務(wù)3.3 用戶輸入猜測數(shù)字的正確數(shù)字和位置xAyB;任務(wù)3.4 根據(jù)猜測結(jié)果,過濾排除候選數(shù)字;
任務(wù)3.5 若猜測正確或猜測次數(shù)>10,結(jié)束猜測;否則,轉(zhuǎn)任務(wù)3.2。
3.2 教學(xué)內(nèi)容與案例目標的分解
結(jié)合案例分析,循序漸進地教學(xué)設(shè)計,教學(xué)內(nèi)容與案例任務(wù)結(jié)合如下:
3.2.1教學(xué)內(nèi)容
(1)選擇結(jié)構(gòu):任務(wù)1.3 判斷猜測的正確性;
(2)循環(huán)結(jié)構(gòu):任務(wù)1.4 繼續(xù)猜測,直至猜對;任務(wù)2.4 重復(fù)猜測直至 猜對,或者猜測次數(shù)>10;
(3)函數(shù):任務(wù)2.1 產(chǎn)生一個無重復(fù)四位數(shù);任務(wù)2.3 分析猜測結(jié)果,得出xAyB;任務(wù)3.2 產(chǎn)生下一個猜測數(shù)字;任務(wù)3.4 過濾排除候選數(shù)字;
(4)數(shù)組:任務(wù)2.3.1將四位數(shù)的各位分離;利用二維數(shù)組進行數(shù)據(jù)結(jié)構(gòu)設(shè)計;
(5)指針、STL::list:利用鏈表、list進行數(shù)據(jù)結(jié)構(gòu)設(shè)計。
3.3 流程設(shè)計
3.3.1問題1 的流程設(shè)計
step1. 初始化,產(chǎn)生一個1-100之間的隨機數(shù);
step2. 判斷猜測正確或猜測次數(shù)>10,若是轉(zhuǎn)step5.
step3. 用戶輸入猜測數(shù)字;
step4. 分析猜測結(jié)果,并反饋;猜測次數(shù)增1,返回step2.
step5. 輸出猜測結(jié)果。
3.3.2問題2 的流程設(shè)計
step1. 初始化,產(chǎn)生一個無重復(fù)四位數(shù)myRand(); 分離各位數(shù)字separate();
step2. 判斷猜測正確或猜測次數(shù)>10,若是轉(zhuǎn)step5.
step3. 用戶輸入猜測數(shù)字;
step4. 分離并分析猜測結(jié)果,并反饋;猜測次數(shù)增1,返回step2.
step5. 輸出猜測結(jié)果。
3.3.3問題3的設(shè)計與分析
(1)數(shù)據(jù)結(jié)構(gòu)設(shè)計。
方案一: 定義二維數(shù)組tree[4540][6],存放格式:{1, 2, 3,4, 1234, 0} ,最后分量取值為0表示尚未排除,取值為-1表示已排除,取值>0表示很可能候選。
方案二:定義鏈表決策樹tree,存放所有候選4位數(shù)字,若排除某個候選數(shù)字,則刪除此結(jié)點,最后直至剩下1個或0個。
方案三:利用STL的list定義主數(shù)據(jù)結(jié)構(gòu)tree,可以利用STL::list提供的函數(shù),更方便地進行數(shù)據(jù)存儲和處理。
(2)主流程設(shè)計。
step1. 初始化tree。void init(){}//將所有四位不重復(fù)的數(shù)字,從小到大存放在tree中,1023 1024 … 9876。
step2. 產(chǎn)生一個候選數(shù)字guessNext()。取下一個候選數(shù)字;返回值-1表示沒有答案;
step3. 用戶輸入猜測數(shù)字的正確數(shù)字和位置xAyB;
step4. 將所有tree中候選數(shù)字逐一比較是否滿足xAyB,不滿足則排除掉;void filter(int n){ }
step5. 轉(zhuǎn)step2.
4 代碼設(shè)計與調(diào)試
問題1可以根據(jù)教學(xué)內(nèi)容在課堂上進行代碼的逐步完善,并演示基本的代碼調(diào)試技巧。對于問題2在課堂上進行主流程分析后,編寫代碼框架,讓學(xué)生在課下進行代碼的具體編寫和調(diào)試。
問題2的程序主框架
int myRand(){//產(chǎn)生一個四位數(shù),各位數(shù)字互不重復(fù)
/*產(chǎn)生1-9之間的隨機數(shù)a;產(chǎn)生0-9之間的隨機數(shù)b、c、d,且abcd均互不相同。*/
res=a*1000+b*100+c*10+d; return res; }
void seperate(int num,int ans[]){//將一個四位數(shù)各位分離,存放在數(shù)組中
//將4位數(shù)num,分離出千、百、十、個位,存放在ans[0]、ans[1]、ans[2]、ans[3]中。}
void compare(int guess[], int answer[], int & digit, int& location){
//比較guess與answer,猜對了digit個數(shù)字,猜對了location個位置 略}
int main(){
int guess=0,guessDigits[4]={0},guessTimes=0; //數(shù)據(jù)結(jié)構(gòu)定義
int answer=1234,answerDigits[4]={0}; int digitOK=0,locationOK=0; int i=0,j=0;
answer=myRand();//產(chǎn)生一個四位數(shù)
seperate(answer,answerDigits);//將答案各位數(shù)分離
while(digitOK<=4 && locationOK<4 &&guessTimes<10){ //開始猜測
guessTimes++;
cout< cin>>guess;//輸入用戶猜測 seperate(guess,guessDigits); //將猜測各位數(shù)分離 compare(guessBits,answerDigits,digitOK,locationOK);//判斷猜測結(jié)果 cout<<"\b "< if(guessTimes>=10 &&locationOK<4)//輸出猜測結(jié)果 cout<<"Guess more than 10 times,you lose the game.\n"; else{cout<<"you win the game.\n"; } return 0; } 利用STL::list方案進行問題3的思路設(shè)計,提供一個思路,讓學(xué)生自行實現(xiàn)程序。 list int guessed[11][3]={{0}};//存放所有猜測過的數(shù)字與反饋結(jié)果 void init(){//初始化決策樹,分別存放1023,1024,…,9875,存放格式為1 0 2 3 1023 0(-1或1) //略 tree.empty(); i=tree.begin(); //略 tree.push_back(n); i++; //略 } //產(chǎn)生下一個猜測數(shù)字,n表示猜測次數(shù) int guessNext(int n){ int res=1234; list if(n==1) return res; i=tree.begin(); if(!tree.empty()){//取出候選數(shù)字} else{cout<<"you are cheating.\n"; res=-1;}
return res; }
bool compare(int ans,int gue,int x,int y){ //判斷gue與ans的反饋信息是否符合xAyB
/*分離ans和gue的各位數(shù)字; 判斷數(shù)字正確個數(shù)是否為x個;判斷數(shù)字和位置均正確個數(shù)是否為y個*/ }
//根據(jù)猜測結(jié)果,篩選過濾候選數(shù)字,留下滿足xAyB反饋的數(shù)字,去除不滿足的候選數(shù)字。
void filter(int n){
//略
x=guessed[n][1];y=guessed[n][2];
while(i!=tree.end()){
if(compare(*i,guessed[n][0],A,B)){//符合反饋信息
i++;}
else{ //排除掉該候選數(shù)字
i=tree.erase(i); } } }
int main(){//主函數(shù)
int numOK=0,locationOK=0,guess=1234,n=0;
init();
while(guess!=-1 && locationOK<4 && n<=10){ //尚未反饋4A4B, 且猜測次數(shù)<10
guess=guessNext(n+1);
if(guess==-1)break;//沒有正確數(shù)字,退出
cout<<++n<<"th guess: "< cin>>numOK>>locationOK;//存放猜測數(shù)字以及反饋信息 filter(n);//過濾排除候選數(shù)字 } return 0; } 5 結(jié)語 從教學(xué)實踐情況來看,這種教學(xué)設(shè)計方式確定了課程的實施方案及操作步驟,以提高學(xué)生學(xué)習(xí)積極性和主動性為導(dǎo)引,能夠及時獲得反饋,取得了很好的教學(xué)效果。如何能更加合理地運用更好的教學(xué)方式去教學(xué),還是有很多內(nèi)容值得我們?nèi)嵺`和探索的。 參考文獻 [1] 吳文虎.我怎么講好“程序設(shè)計基礎(chǔ)”這門課[J].中國大學(xué)教學(xué),2011(12):10-12. [2] 李可.編寫小型游戲程序在C++教學(xué)中的一點應(yīng)用心得[J].科技資訊,2008(27):19-20. [3] 王之元,易曉東,李姍姍.面向MOOC的程序設(shè)計語言課程教學(xué)設(shè)計[J].計算機教育,2014(2):55-58. [4] 何欽銘.“程序設(shè)計基礎(chǔ)”課程教學(xué)實施方案[J].中國大學(xué)教學(xué),2010(5):62-65. [5] 劉芳.《C語言程序設(shè)計》教學(xué)存在的問題及改進[J].教育理論與實踐,2012,32(36):51-52. [6] 孫慧然.“程序設(shè)計基礎(chǔ)課”理論與實驗教學(xué)的改革與實踐[J].實驗技術(shù)與管理,2012,29(4):299-300. [7] 教育部高等學(xué)校計算機科學(xué)與技術(shù)教學(xué)指導(dǎo)委員會.高等學(xué)校計算機科學(xué)與技術(shù)專業(yè)核心課程教學(xué)實施方案[M].北京:高等教育出版社,2009. [8] 譚浩強.C++程序設(shè)計(第2版)[M].北京:清華大學(xué)出版社,2013.