电脑游戏中的人工智能制作

  电脑游戏随着硬件执行效率和显示解析度等大幅提升以往很多不可能或非常难以实现电脑游戏如此都得以顺利完成虽然电脑游戏呈现是那么地多样化然而却和我们今日所要探讨主题人工智能几乎都有着密不可分关系
 在角色扮演游戏中员和企划人员需要精确地在电脑上将个个所谓“怪物”在战门过程中栩栩如生地制作出来;所以半兽人受了重伤懂得逃跑法师懂得施展攻性法术
 目前能让人立刻想到和人工智能有密切关系游戏有两种:
是所谓战棋/策略模拟游戏 2则是棋弈游戏人工智能比重和深浅度在区别游戏类型中各有不电脑游戏非标榜着高人工智能不可不然没有人买;有则是几乎渺茫到让玩家无法感觉有任何人工智能存在            

 导向式研究

 AI最容易制作方式同时也是早期游戏AI发展主要方向就是规则导向或称的为假设导向些比较简单电脑游戏中员可以好不困难地将游戏中规则和设定转化成条条规则然后将它们写成电脑让我们以角色扮演游戏为例决大多数企画在设定所谓电脑怪物时所设定属性通常有以下几种:

  生命值 攻击力 防御力 法力  属性

 最后个“属性”是我在设定时喜欢增加项目的透过这项属性设定我可以把怪物设定成“贪生怕死也可以把战士设定为“视死如归”以目前我们所掌握资料在战门系统中大纲如是诞生了:                          

规则

(生命值< 10) // 边临死亡了吗 
{  (属性 贪生怕死)               
   结果 = 试图逃跑               
   (有任何恢复生命值物品或法术可用)      
   结果 = 使用或施展相关物品或法术       
}                                                 

规则 2
 
(可施攻击性法术 && 有足够法力)
{                        
   结果 = 施展攻攻击性法术             
}                        

 由以上连串“如果--就--”规则设定建立了最基本AI说这样制方式只能建立基本AI其实并不当然正确只要建立足够及精确规则这样方式仍然有定水准表现
 规则导向最大优点就是易学易用在没有深奥理论概念前提下仍有广大使用群所以很多老道玩家常常没两下就摸清楚敌人攻击策略移动方式等等

 推论式研究

 相信曾经接触过电脑语言课程或是自习过相关书籍朋友们都曾曾经听过个著名那就是井字游戏用井字游戏作为讨论AI入门教材我个人觉得是最适当例子或许有人还不知道井字游戏如何玩只要任何方在 3乘 3方格中先先成线便胜利了我们在前面谈过规则导向在这里也可以派得上用场

 任何线已有我方两子&&另外格仍空//我方即将成线吗
  结果 = 该空格                     
 任何线已有敌方两子&&另外格仍空//防止敌方作成线 
  结果 = 该空格                     
 任何线已有我方子&&另外两格仍空//作成两子    
  结果 = 该空格

 有次我在某本电脑书上同样地也看到某些以井字游戏为介绍范例区别我几乎看不到任何规则导向影子但在仔细分析该码后我得到了极大启发原来AI是可以不用这么多规则来制作它用思路方法正是在电脑AI课程中重要概念:极大极小法我在这里只介绍说明这法则概念继续以井字游戏为例电脑先在某处下子接着会以假设方式替对方下子当然必须假设对方下是最佳位置否则切则毫无意义在假设对方下子过程中自然又需要假设我方步回应如此直到下完整局游戏为止 底下是节录书中片段:                       
 
bestMove( p, *v)
{    i; 
    lastTie;                  
    lastMove;                 
    subV;                                   
/*First, check for a tie*/            
     (isTie) {              
     *v=0;               
     (0);              
   };
/*If not a tie, try each potential move*/
 for (*v=-1, lastTie=lastMove=-1,i=0;i<9;i)
  {
   /*If this isn't a possible, skip it*/          
    (board[i]!=0) continue;
   /* Make the move. */
    lastMove=i; 
    board[i]=p;                             
   /* Did it win? */                       
     (hasWon(p)) *v=1;                     
    {                             
   /*If not, find out how good the other side can do*/
     bestMove(-p,&subV);                      
   /* If they can _disibledevent=0) (lastTie);                      
/*If there weren't even any ties, a loosing move.*/     
   (lastMove); 
};    

 国外些论坛曾举行过256字节游戏设计比赛作品非常多其中有件作品正巧也是井字游戏作者用区区两百多行就写了和上述演算方式完全相同作品可见功力确实了另外我也很希望类似活动能在国内推展起来对了在这样比赛条件限制下除了汇编语言外几乎没有其它选择了       .386c                        
  code      segment public use16      
          assume cs:code, ds:code      
                            
          org   100h            
                            
  tictac     proc  far             
                            
  start:                       
          push  cs             
          pop   ds             
          mov   ax,0B800h     ; 清除屏幕
          mov   es,ax       ;    
          xor   di,di       ;    
          mov   cx,7D0h      ;    
          mov   ax,0F20h      ;    
          rep   stosw       ;    
          xor   cx,cx       ;    
          mov   dl,5            
  loc_1:                       
          call  prBoard         
  loc_2:                       
          mov   ah,8        ; 等待按键
             21h             
                            
          movzx  bx,al            

          sub   bl,31h       ; 如果不是1..9
          jc   loc_2       ; 则重新输入 
          cmp   bl,8              
          ja   loc_2              
          cmp   data_1[bx],al          
          jne   loc_2              
          mov   ptr data_1[bx],'x'     
          dec   dl               
          jz    loc_3           
          mov   al,'o'             
          call  bestMove            
          mov   [si],al             
          call  isWin   ; 判断是否已取得胜利 
          jnc   loc_1              
  loc_3:                          
          call  prBoard           
          mov   ax,4C00h            
             21h               
                              
  data_1     db   '12'              
  data_2     db   '3456789'            
  data_3     db   0                
                              
  tictac     endp                  
                              
                              
  prBoard   proc  near              
          mov   si,off data_1        
          mov   di,548h             
          mov   cl,3              
                              
  locloop_4:                       
          movsb                  
          add   di,5              
          movsb                  
          add   di,5              
          movsb                  
          add   di,133h             
          loop  locloop_4            
                              
          retn                  
  prBoard   endp                  
                              
                              
  isWin      proc  near              
          mov   bx,1              
          mov   bp,3              
          call  sub_3    ; 检查横向是否完成 
          inc   bx               
          inc   bx               
          dec   bp               
          dec   bp               
          call  sub_3    ; 检查纵向是否完成 
          call  sub_4    ; 检查斜向是否完成
          clc
          retn                  
  isWin      endp                  
                              
  loc_5:                         
          stc                   
          retn                  
                                                            
  sub_3      proc  near              
          mov   ah,3              
          mov   si,off data_1        
  loc_6:                         
          mov   di,si              
          call  sub_5              
          add   si,bp             
          dec   ah               
          jnz   loc_6              
          retn                  
  sub_3      endp                  
                             
  sub_4      proc  near              
          mov   di,off data_1       
          inc   bx              
          call  sub_5             
          mov   di,off data_2        
          dec   bx               
          dec   bx               
          call  sub_5              
          retn                  
  sub_4      endp                  
                              
                              
  sub_5      proc  near              
          mov   cl,3              
                              
  locloop_7:                       
          cmp   [di],al             
          jne   loc_ret_8         
          add   di,bx              
          loop  locloop_7            
                              
          add   sp,4              
          jmp   loc_5           
                              
  loc_ret_8:                       
          retn                      
  sub_5      endp                      
                                  
  bestMove    proc  near                  
          mov   bx,31FEh                
          mov   cl,9                  
          mov   di,off data_1            
                                  
  locloop_9:                           
          cmp   [di],bh     ; #empty?        
          jne   loc_12  ; #no, skip       
          mov   [di],al                 
          pusha                      
          call  isWin      ; #CY: Win       
          popa          ;            
          jnc   loc_10  ;            
          mov   bl,1                  
          mov   si,di                  
          mov   [di],bh                 
          retn                      
  loc_10:                             
          pusha                      
          xor   al,17h ; good! toggle 'o' / 'x'
          call  bestMove                
          mov   data_3,bl                
          popa                      
          mov   ah,data_3                
          neg   ah                   
          cmp   ah,bl                  
          jle   loc_11              
          mov   bl,ah                  
          mov   si,di                  
  loc_11:                             
          mov   [di],bh                 
  loc_12:                             
          inc   bh                   
          inc   di                   
          loop  locloop_9                
                                  
          cmp   bl,0FEh                 
          jne   loc_ret_13            
          xor   bl,bl                  
                                  
  loc_ret_13:                           
          retn                      
  bestMove    endp                      
  code      ends

          end   start
Tags: 

延伸阅读

最新评论

  1. 看不懂耶
  2. kan bu dong ya

发表评论