Subversion Repositories Kolibri OS

Rev

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