?? 電腦游戲中的人工智能制作.htm
字號:
<HTML><HEAD><TITLE>電腦游戲中的人工智能制作</TITLE>
<BODY aLink=#990000 bottomMargin=0 leftMargin=0 rightMargin=0
topMargin=0 marginheight="0" marginwidth="0">
<CENTER>
<DIV align=center>
<DIV align=left class=fst>
<DIV class=fstdiv3
id=print2><BR><BR>電腦游戲隨著硬件執(zhí)行效率與顯示解析度等大幅提升,以往很多不可能或非常難以實現(xiàn)的電腦游戲如此都得以順利完成。雖然電腦游戲的呈現(xiàn)是那么地多樣化,然而卻與我們今日所要探討的主題,人工智能幾乎都有著密不可分的關系。
<BR> 在角色扮演游戲中,程序員與企劃人員需要精確地在電腦上將一個個所謂的“怪物”在戰(zhàn)門過程中栩栩如生地制作出來;所以半獸人受了重傷懂得逃跑,法師懂得施展攻性法術。
<BR> 目前能讓人立刻想到與人工智能有密切關系的游戲有兩種:
<BR> 一是所謂的戰(zhàn)棋/策略模擬游戲,二則是棋弈游戲。人工智能的比重與深淺度,在不同的游戲類型中各有不一。有的電腦游戲非標榜著高人工智能不可,不然沒有人買;有的則是幾乎渺茫到讓玩家無法感覺有任何人工智能的存在。
<BR><BR> 導向式思考
<BR><BR> ai最容易制作的的方式,同時也是早期游戲ai發(fā)展的主要方向就是規(guī)則導向或稱之為假設導向。在一些比較簡單的電腦游戲中,程序員可以好不困難地將游戲中的規(guī)則與設定轉化成一條條的規(guī)則,然后將它們寫成電腦程序。讓我們以角色扮演游戲為例。決大多數(shù)的企畫在設定所謂電腦怪物時,所設定的屬性通常有以下幾種:
<BR><BR> 生命值 攻擊力 防御力 法力 屬性
<BR><BR> 最后一個“屬性”是我在設定時喜歡增加的項目之一。透過這項屬性的設定,我可以把怪物設定成“貪生怕死的”,也可以把戰(zhàn)士設定為“視死如歸”。以目前我們所掌握的資料,在戰(zhàn)門系統(tǒng)中的大綱如是誕生了:
<BR><BR>規(guī)則一 <BR><BR>if (生命值< 10) // 邊臨死亡了嗎
<BR>{ if (屬性== 貪生怕死)
<BR> 結果 = 試圖逃跑
<BR> if (有任何恢復生命值的物品或法術可用)
<BR> 結果 = 使用或施展相關物品或法術
<BR>} <BR> <BR><BR>規(guī)則二
<BR> <BR>if (可施攻擊性法術 && 有足夠法力)
<BR>{
<BR> 結果 = 施展攻攻擊性法術
<BR>}
<BR><BR> 由以上一連串的“如果--就--”規(guī)則設定,建立了最基本的ai。說這樣的制方式只能建立基本ai其實并不當然正確。只要建立足夠及精確的規(guī)則,這樣的方式仍然有一定水準的表現(xiàn)。
<BR> 規(guī)則導向的最大優(yōu)點就是易學易用。在沒有深奧的理論概念的前提下,仍有廣大的使用群。所以很多老道的玩家常常沒兩下就摸清楚敵人的攻擊策略,移動方式等等。
<BR><BR> 推論式思考
<BR><BR> 相信曾經(jīng)接觸過電腦語言課程,或是自習過相關書籍的朋友們,都曾曾經(jīng)聽過一個著名的程序,那就是井字游戲。用井字游戲作為討論ai的入門教材,我個人覺得是最適當?shù)睦??;蛟S有人還不知道井字游戲怎么玩。只要任何一方在三乘三的方格中先先成一線便勝利了。我們在前面談過的規(guī)則導向,在這里也可以派得上用場。
<BR><BR> if任何一線已有我方兩子&&另外一格仍空//我方即將成一線嗎
<BR> 結果 = 該空格
<BR> if任何一線已有敵方兩子&&另外一格仍空//防止敵方作成一線
<BR> 結果 = 該空格
<BR> if任何一線已有我方一子&&另外兩格仍空//作成兩子 <BR> 結果 = 該空格
<BR><BR> 有一次我在某本電腦書上,同樣地也看到某些以井字游戲為介紹的范例。不同的是,我?guī)缀蹩床坏饺魏我?guī)則導向的影子。但在仔細分析該程序碼后,我得到了極大的啟發(fā),原來ai是可以不用這么多規(guī)則來制作的。它用的方法正是在電腦ai課程中重要的概念:極大極小法。我在這里只說明這法則的概念。繼續(xù)以井字游戲為例,電腦先在某處下子,接著會以假設的方式,替對方下子,當然,必須假設對方下的是最佳位置,否則一切則毫無意義。在假設對方下子的過程中,自然又需要假設我方的下一步回應,如此一來一往,直到下完整局游戲為止。
<BR><BR>底下是節(jié)錄書中的程序片段: <BR>
<BR>bestmove(int p, int*v) <BR>{ int i;
<BR> int lasttie;
<BR> int lastmove;
<BR> int subv;
<BR>/*first, check for a tie*/
<BR> if (istie()) {
<BR> *v=0; <BR> return(0);
<BR> };
<BR>/*if not a tie, try each potential move*/
<BR> for (*v=-1, lasttie=lastmove=-1,i=0;i<9;i++)
<BR> {
<BR> /*if this isn't a possible, skip it*/
<BR> if (board[i]!=0) continue;
<BR> /* make the move. */ <BR> lastmove=i;
<BR> board[i]=p;
<BR> /* did it win? */
<BR> if (haswon(p)) *v=1;
<BR> else{
<BR> /*if not, find out how good the other side can do*/
<BR> bestmove(-p,&subv);
<BR> /* if they can only lose, this is still a win.*/
<BR> if (subv==-1) *v=1;
<BR> /* or, if it's a tie, remember it. */
<BR> else if (subv==0){
<BR> *v=0; <BR> lasttie=i;
<BR> };
<BR> };
<BR>/* take back the move. */
<BR> board[i]=0;
<BR>/*if we found a win, return immediately
<BR> (can't do any better than that)*/
<BR> if (*v==1) return(i);
<BR>/*if we didn't find any wins, return a tie move.*/
<BR> if (*v==0) return(lasttie);
<BR>/*if there weren't even any ties, return a loosing move.*/
<BR> else return(lastmove); <BR>};
<BR><BR> 國外的一些論壇曾舉行過256字節(jié)的游戲設計比賽。作品非常多,其中有一件作品正巧也是井字游戲。作者用區(qū)區(qū)兩百多行就寫了與上述程序演算方式完全相同的作品,可見功力確實了的。另外,我也很希望類似的活動能在國內推展起來。對了,在這樣的比賽條件限制下,除了匯編語言外,幾乎沒有其它的選擇了?! ?
<BR><BR> .386c
<BR> code segment byte public use16
<BR> assume cs:code, ds:code
<BR>
<BR> org 100h
<BR> <BR> tictac proc far
<BR> <BR> start:
<BR> push cs
<BR> pop ds
<BR> mov ax,0b800h ; 清除屏幕
<BR> mov es,ax ;
<BR> xor di,di ;
<BR> mov cx,7d0h ;
<BR> mov ax,0f20h ;
<BR> rep stosw ;
<BR> xor cx,cx ;
<BR> mov dl,5
<BR> loc_1:
<BR> call printboard
<BR> loc_2:
<BR> mov ah,8 ; 等待按鍵
<BR> int 21h <BR>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -