Go to most recent revision | Details | 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 _BOARD_INC |
||
22 | %define _BOARD_INC |
||
23 | |||
24 | |||
25 | ;********************************************************** |
||
26 | ; magic numbers |
||
27 | ;********************************************************** |
||
28 | |||
29 | EMPTY equ 0 |
||
30 | PLAYER1 equ 1 |
||
31 | PLAYER2 equ 2 |
||
32 | |||
33 | ; board dimensions (+2 for border) |
||
34 | BWIDTH equ 9 |
||
35 | BHEIGHT equ 8 |
||
36 | |||
37 | |||
38 | |||
39 | ;********************************************************** |
||
40 | ; uninitialized data |
||
41 | ;********************************************************** |
||
42 | |||
43 | section .bss |
||
44 | |||
45 | board resd BHEIGHT*BWIDTH ; the board |
||
46 | free resd BWIDTH ; # of free fields for each column |
||
47 | totalfree resd 1 ; total # of free fields |
||
48 | currentplayer resd 1 ; player to make next move |
||
49 | lastmove resd 1 ; last move done on the board |
||
50 | ; (0 if no last move available) |
||
51 | |||
52 | |||
53 | |||
54 | ;********************************************************** |
||
55 | ; code |
||
56 | ;********************************************************** |
||
57 | |||
58 | section .text |
||
59 | |||
60 | |||
61 | ;********************************************************** |
||
62 | ; boardReset |
||
63 | ; reset board for new game |
||
64 | ; |
||
65 | ; input : nothing |
||
66 | ; output : nothing |
||
67 | ; destroys : nothing |
||
68 | ;********************************************************** |
||
69 | boardReset: |
||
70 | pushfd |
||
71 | pushad |
||
72 | |||
73 | ; clear all fields |
||
74 | mov edi,board |
||
75 | mov ecx,BHEIGHT * BWIDTH |
||
76 | mov eax,EMPTY |
||
77 | rep stosd |
||
78 | |||
79 | ; init free array |
||
80 | mov edi,free |
||
81 | mov ecx,BWIDTH |
||
82 | mov eax,BHEIGHT - 2 |
||
83 | rep stosd |
||
84 | |||
85 | mov dword [totalfree],(BWIDTH-2)*(BHEIGHT-2) |
||
86 | mov dword [currentplayer],PLAYER1 |
||
87 | mov dword [lastmove],0 |
||
88 | |||
89 | popad |
||
90 | popfd |
||
91 | ret |
||
92 | |||
93 | |||
94 | |||
95 | ;********************************************************** |
||
96 | ; BOARDISVALIDMOVE |
||
97 | ; checks wether a move is valid |
||
98 | ; |
||
99 | ; input : 32 bit register containing a move |
||
100 | ; number (1..7) |
||
101 | ; output : zero flag set -> move is invalid |
||
102 | ; zero flag clear -> move is valid |
||
103 | ; destroys : nothing |
||
104 | ;********************************************************** |
||
105 | %macro BOARDISVALIDMOVE 1 |
||
106 | cmp dword [free+%1*4],0 |
||
107 | %endmacro |
||
108 | |||
109 | |||
110 | |||
111 | ;********************************************************** |
||
112 | ; boardMakeMove |
||
113 | ; make a move |
||
114 | ; |
||
115 | ; input : eax = move number (1..7) |
||
116 | ; ebx = PLAYER1/PLAYER2 |
||
117 | ; output : nothing |
||
118 | ; destroys : edi, flags |
||
119 | ;********************************************************** |
||
120 | |||
121 | boardMakeMove: |
||
122 | mov edi,[free+eax*4] ; place stone |
||
123 | imul edi,BWIDTH |
||
124 | add edi,eax |
||
125 | mov [board+edi*4],ebx |
||
126 | |||
127 | dec dword [free+eax*4] ; one stone more in this column |
||
128 | dec dword [totalfree] ; one stone more on the board |
||
129 | mov [lastmove],eax ; store move for undo |
||
130 | ret |
||
131 | |||
132 | |||
133 | |||
134 | ;********************************************************** |
||
135 | ; boardUndoMove |
||
136 | ; undo a move |
||
137 | ; |
||
138 | ; input : eax = move number to undo (1..7) |
||
139 | ; output : move is undone |
||
140 | ; destroys : edi, flags |
||
141 | ;********************************************************** |
||
142 | boardUndoMove: |
||
143 | inc dword [free+eax*4] ; one stone less in this column |
||
144 | inc dword [totalfree] ; one stone less on the board |
||
145 | mov dword [lastmove],0 ; no last move available |
||
146 | |||
147 | mov edi,[free+eax*4] ; remove stone from board |
||
148 | imul edi,BWIDTH |
||
149 | add edi,eax |
||
150 | mov dword [board+edi*4],EMPTY |
||
151 | ret |
||
152 | |||
153 | |||
154 | |||
155 | ;********************************************************** |
||
156 | ; BOARDSWITCHPLAYERS |
||
157 | ; switch current player |
||
158 | ; |
||
159 | ; input : nothing |
||
160 | ; output : current player is switched |
||
161 | ; destroys : flags |
||
162 | ;********************************************************** |
||
163 | %macro BOARDSWITCHPLAYERS 0 |
||
164 | xor dword [currentplayer],(PLAYER1 ^ PLAYER2) |
||
165 | %endmacro |
||
166 | |||
167 | |||
168 | |||
169 | ;********************************************************** |
||
170 | ; BOARDGETOTHERPLAYER |
||
171 | ; get other player =) |
||
172 | ; |
||
173 | ; input : 32 bit register or variable |
||
174 | ; output : player changed |
||
175 | ; destroys : flags |
||
176 | ;********************************************************** |
||
177 | %macro BOARDGETOTHERPLAYER 1 |
||
178 | xor %1,(PLAYER1 ^ PLAYER2) |
||
179 | %endmacro |
||
180 | |||
181 | |||
182 | |||
183 | ;********************************************************** |
||
184 | ; BOARDISFULL |
||
185 | ; check wether board is full |
||
186 | ; |
||
187 | ; input : nothing |
||
188 | ; output : zero flag set -> board is full |
||
189 | ; zero flag clear -> board isn't full |
||
190 | ;********************************************************** |
||
191 | %macro BOARDISFULL 0 |
||
192 | cmp dword [totalfree],0 |
||
193 | %endmacro |
||
194 | |||
195 | |||
196 | |||
197 | ;********************************************************** |
||
198 | ; boardIsWin |
||
199 | ; check wether the current board state is a win for the |
||
200 | ; given player |
||
201 | ; |
||
202 | ; input : eax = player |
||
203 | ; output : eax = nonzero -> win for player |
||
204 | ; destroys : everything |
||
205 | ;********************************************************** |
||
206 | |||
207 | boardIsWin: |
||
208 | |||
209 | ; check wether last move is available |
||
210 | cmp dword [lastmove],0 |
||
211 | jne .lastmoveok |
||
212 | xor eax,eax |
||
213 | ret |
||
214 | .lastmoveok: |
||
215 | |||
216 | ; calculate the address of the most recently placed stone (edi) |
||
217 | mov edi,[lastmove] |
||
218 | mov esi,[free + edi*4] |
||
219 | inc esi |
||
220 | imul esi,BWIDTH |
||
221 | add edi,esi |
||
222 | shl edi,2 |
||
223 | add edi,board |
||
224 | |||
225 | ; check vertically |
||
226 | xor ecx,ecx ; reset counter |
||
227 | mov esi,edi ; start at last stone |
||
228 | .vertical: |
||
229 | cmp [esi],eax ; loop as long the stone [esi] belongs to player |
||
230 | jne .verticalend |
||
231 | add esi,BWIDTH*4 ; move to next stone |
||
232 | inc ecx ; one stone more in row |
||
233 | jmp short .vertical |
||
234 | .verticalend: |
||
235 | cmp ecx,4 ; 4 or more stones ? |
||
236 | jl .nope1 ; nope -> continue |
||
237 | mov eax,1 ; yeah -> tell caller =) |
||
238 | ret |
||
239 | .nope1: |
||
240 | |||
241 | ; check horizontally |
||
242 | xor ecx,ecx |
||
243 | mov esi,edi |
||
244 | .horizontal1: ; left |
||
245 | cmp [esi],eax |
||
246 | jne .horizontalend1 |
||
247 | sub esi,4 |
||
248 | inc ecx |
||
249 | jmp short .horizontal1 |
||
250 | .horizontalend1: |
||
251 | lea esi,[edi+4] ; right |
||
252 | .horizontal2: |
||
253 | cmp [esi],eax |
||
254 | jne .horizontalend2 |
||
255 | add esi,4 |
||
256 | inc ecx |
||
257 | jmp short .horizontal2 |
||
258 | .horizontalend2: |
||
259 | cmp ecx,4 |
||
260 | jl .nope2 |
||
261 | mov eax,1 |
||
262 | ret |
||
263 | .nope2: |
||
264 | |||
265 | ; diagonally forward |
||
266 | xor ecx,ecx |
||
267 | mov esi,edi |
||
268 | .forward1: |
||
269 | cmp [esi],eax |
||
270 | jne .forwardend1 |
||
271 | sub esi,(1+BWIDTH)*4 |
||
272 | inc ecx |
||
273 | jmp short .forward1 |
||
274 | .forwardend1: |
||
275 | lea esi,[edi+(1+BWIDTH)*4] |
||
276 | .forward2: |
||
277 | cmp [esi],eax |
||
278 | jne .forwardend2 |
||
279 | add esi,(1+BWIDTH)*4 |
||
280 | inc ecx |
||
281 | jmp short .forward2 |
||
282 | .forwardend2: |
||
283 | cmp ecx,4 |
||
284 | jl .nope3 |
||
285 | mov eax,1 |
||
286 | ret |
||
287 | .nope3: |
||
288 | |||
289 | ; diagonally backward |
||
290 | xor ecx,ecx |
||
291 | mov esi,edi |
||
292 | .backward1: |
||
293 | cmp [esi],eax |
||
294 | jne .backwardend1 |
||
295 | add esi,(1-BWIDTH)*4 |
||
296 | inc ecx |
||
297 | jmp short .backward1 |
||
298 | .backwardend1: |
||
299 | lea esi,[edi+(BWIDTH-1)*4] |
||
300 | .backward2: |
||
301 | cmp [esi],eax |
||
302 | jne .backwardend2 |
||
303 | add esi,(BWIDTH-1)*4 |
||
304 | inc ecx |
||
305 | jmp short .backward2 |
||
306 | .backwardend2: |
||
307 | cmp ecx,4 |
||
308 | jl .nope4 |
||
309 | mov eax,1 |
||
310 | ret |
||
311 | .nope4: |
||
312 | |||
313 | ; no win for this player |
||
314 | xor eax,eax |
||
315 | ret |
||
316 | |||
317 | |||
318 | %endif |