在角色扮演游戏中员和企划人员需要精确地在电脑上将个个所谓“怪物”在战门过程中栩栩如生地制作出来;所以半兽人受了重伤懂得逃跑法师懂得施展攻性法术
目前能让人立刻想到和人工智能有密切关系游戏有两种:
是所谓战棋/策略模拟游戏 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
2008-12-27 at 10:41
2009-1-13 at 18:03