Subversion Repositories Kolibri OS

Rev

Rev 109 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
31 halyavin 1
; C4
2
; Copyright (c) 2002 Thomas Mathys
3
; killer@vantage.ch
4
;
5
; This file is part of C4.
6
;
7
; C4 is free software; you can redistribute it and/or modify
8
; it under the terms of the GNU General Public License as published by
9
; the Free Software Foundation; either version 2 of the License, or
10
; (at your option) any later version.
11
;
12
; C4 is distributed in the hope that it will be useful,
13
; but WITHOUT ANY WARRANTY; without even the implied warranty of
14
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
; GNU General Public License for more details.
16
;
17
; You should have received a copy of the GNU General Public License
18
; along with C4; if not, write to the Free Software
19
; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
 
21
%ifndef _AI_INC
22
%define _AI_INC
23
 
24
 
25
INFTY		equ	1000000000
26
 
27
 
28
 
29
	section .data
30
 
31
; table used to perform some primitive move "ordering":
32
; middle columns which are usually more important are
33
; searched first.
34
moveorder	dd	1,7,2,6,3,5,4
35
 
36
; table used for static evaluation.
37
; this table is taken from 4st attack: it is ways better
38
; than the table i used before =)
39
evaltable:	dd	 0, 0, 0, 0, 0, 0, 0, 0, 0
40
		dd	 0, 3, 4, 5, 7, 5, 4, 3, 0
41
		dd	 0, 4, 6, 8,10, 8, 6, 4, 0
42
		dd	 0, 5, 8,12,13,12, 8, 5, 0
43
		dd	 0, 5, 8,12,13,12, 8, 5, 0
44
		dd	 0, 4, 6, 8,10, 8, 6, 4, 0
45
		dd	 0, 3, 4, 5, 7, 5, 4, 3, 0
46
		dd	 0, 0, 0, 0, 0, 0, 0, 0, 0
47
 
48
 
49
 
50
	section .bss
51
 
52
cpulevel	resd	1	; level of current cpu player
53
bestval		resd	1	; value of best move found so far
54
nbestmoves	resd	1	; # of best moves found so far
55
bestmoves	resd	7	; array to hold all best moves
56
 
57
 
58
 
59
	section .text
60
 
61
 
62
 
63
;**********************************************************
64
; aiGetMove
65
; returns a move for a computer player
66
;
67
; input		:	eax = cpu level ( >= 1)
68
; output	:	eax = move
69
; destroys	:	everything
70
;**********************************************************
71
aiGetMove:
72
 
73
	; initialize variables
74
	mov [cpulevel],eax
75
	mov dword [bestval],-INFTY
76
	mov dword [nbestmoves],0
77
 
78
	; try every move
79
	mov ecx,6
80
.evalmoves:
81
 
82
	; get move to make from move order table
83
	mov eax,[moveorder+ecx*4]
84
 
85
	; if this is an invalid move, continue with next move
86
	BOARDISVALIDMOVE eax
87
	jz .nextmove
88
 
89
	; make move for current player
90
	mov ebx,[currentplayer]
91
	call boardMakeMove
92
 
93
	; evaluate move
94
	push eax			; save move #
95
	push ecx			; save loop counter
96
	push dword [cpulevel]		; ply
97
	mov ebx,[currentplayer]		; player
98
	BOARDGETOTHERPLAYER ebx
99
	push ebx
100
	push dword -INFTY		; alpha
101
	push dword INFTY		; beta
102
	call alphabeta
103
	neg eax				; damn, how could i forget this ???
104
	mov ebx,eax			; save result for later
105
	pop ecx				; restore loop counter
106
	pop eax				; restore move #
107
 
108
	; undo move (eax = move #)
109
	call boardUndoMove
110
 
111
	; let's see wether we have a new best move
112
	cmp ebx,[bestval]		; new best value found ?
113
	jle .nonewbestval
114
	mov [bestval],ebx		; yes -> save it
115
	mov dword [nbestmoves],1	; delete everything that was in the list
116
	mov [bestmoves+0],eax		; save move number in list
117
	jmp short .nextmove		; continue with next move
118
.nonewbestval:
119
	cmp ebx,[bestval]		; another best value found ?
120
	jne .nextmove
121
	mov ebx,[nbestmoves]		; yes -> add move to list
122
	mov [bestmoves+ebx*4],eax
123
	inc dword [nbestmoves]
124
 
125
.nextmove:
126
	dec ecx
127
	js .done
128
	jmp .evalmoves
129
.done:
130
 
131
	; randomly pick one of the best moves
132
	call rand			; rand() % nbestmoves
133
	xor edx,edx
134
	div dword [nbestmoves]
135
	mov eax,[bestmoves+edx*4]	; get move from list
136
	ret
137
 
138
	; test code : pick first move from list
139
	mov eax,[bestmoves+0]
140
	ret
141
 
142
 
143
 
144
;**********************************************************
145
; alphabeta
146
;
147
; input		:	see below
148
; output	:	eax = move value
149
; destroys	:	everything
150
;**********************************************************
151
alphabeta:
152
 
153
%define ply	(ebp+20)
154
%define player	(ebp+16)
155
%define alpha	(ebp+12)
156
%define beta	(ebp+ 8)
157
 
158
	enter 0,0
159
 
160
	; win for other player -> end search
161
	mov eax,[player]
162
	BOARDGETOTHERPLAYER eax
163
	call boardIsWin
164
	or eax,eax
165
	jz .nowin
166
	mov eax,-1000000
167
	mov ebx,[ply]
168
	shl ebx,10
169
	sub eax,ebx
170
	leave
171
	ret 4*4
172
.nowin:
173
	; board full but no win -> draw -> end search
174
	BOARDISFULL
175
	jnz .notfull
176
	xor eax,eax
177
	leave
178
	ret 4*4
1821 yogev_ezra 179
.notfull:
31 halyavin 180
	; max search depth reached -> do static evaluation
181
	cmp dword [ply],0
182
	je .staticeval
183
 
184
 
185
	; for each move
186
	mov ecx,6
187
.evalmoves:
188
 
189
	; while (alpha < beta)
190
	mov eax,[alpha]
191
	cmp eax,[beta]
192
	jge .done
193
 
194
	; pick move from move order table
195
	mov eax,[moveorder+ecx*4]
196
 
197
	; invalid move ? if so, continue with next move
198
	BOARDISVALIDMOVE eax
199
	jz .nextmove
200
 
201
	; make move for current player
202
	mov ebx,[player]
203
	call boardMakeMove
204
 
205
	; evaluate move
206
	push eax
207
	push ecx
208
	mov eax,[ply]			; ply = ply-1
209
	dec eax
210
	push eax
211
	mov ebx,[player]		; player = other player
212
	BOARDGETOTHERPLAYER ebx
213
	push ebx
214
	mov ecx,[beta]			; alpha = -beta
215
	neg ecx
216
	push ecx
217
	mov edx,[alpha]			; beta = -alpha
218
	neg edx
219
	push edx
220
	call alphabeta
221
	neg eax
222
 
223
	; new alpha ?
224
	cmp eax,[alpha]
225
	jle .nonewalpha
226
	mov [alpha],eax			; yes -> save it
227
.nonewalpha:
228
	pop ecx
229
	pop eax
230
 
231
	; undo move
232
	call boardUndoMove
233
 
234
.nextmove:				; evaluate next move
235
	dec ecx
236
	jns .evalmoves
237
 
238
.done:
239
	mov eax,[alpha]
240
	leave
241
	ret 4*4
242
 
243
	; static evaluation
244
.staticeval:
245
	xor eax,eax
246
	mov esi,BWIDTH*BHEIGHT-1
247
.l:
248
	mov ebx,[board+esi*4]		; get stone from board
249
	cmp ebx,[player]		; player's stone ?
250
	jne .notplayer			; nope -> go on
251
	add eax,[evaltable+esi*4]	; yes -> add stone value to eax
252
	jmp .next			; next stone
253
.notplayer:
254
	cmp ebx,EMPTY			; other player's stone ?
255
	je .empty			; nope -> go on
256
	sub eax,[evaltable+esi*4]	; yes -> sub stone value from eax
257
.empty:
258
 
259
.next:					; next stone
260
	dec esi
261
	jns .l
262
	leave				; eax contains static value
263
	ret 4*4
264
 
265
%undef ply
266
%undef player
267
%undef alpha
268
%undef beta
269
 
270
%endif