-
Notifications
You must be signed in to change notification settings - Fork 3
/
inteligencia_artificial
437 lines (388 loc) · 8.24 KB
/
inteligencia_artificial
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
.module inteligencia_artificial
teclado .equ 0xFF02
pantalla .equ 0xFF00
;posicion .equ 0x0080
;Definimos las subrutinas de este fichero como globales
.globl tirada_maquina
.globl nivel_dificultad
;.globl sumar
;CADENAS GLOBALES
.globl cadena_error
.globl cadena_dificultad
;VARIABLES GLOBALES
.globl posicion
.globl final
.globl jugador1
.globl jugador2
.globl columna
.globl semilla
.globl generador_semilla
.globl indice
.globl asignarturno
.globl incognita
.globl victorias_jugador1
.globl victorias_jugador2
.globl victoria
.globl tiradas
.globl maquina
;Declaramos las subrutinas necesarias en el fichero
.globl rand
.globl imprime_cadena
;Elegir la dificultad de la maquina
nivel_dificultad:
pshu a
lee_dificultad:
ldx #cadena_dificultad ;cargamos la cadena para que el usuario elija la dificultad
jsr imprime_cadena ;ejem...
lda teclado ;leemos de teclado la opcion que ha elejido
cmpa #'e ;si es la e minuscula la guarda
beq guarda_dificultad ;guardado de la dificultad
cmpa #'E
beq guarda_dificultad ;tambien le dejamos que elija esa opcion con la E mayuscula
cmpa #'i ;el nivel inteligente se elige pulsando la i minuscula
beq guarda_dificultad
cmpa #'I ;o la mayuscula
beq guarda_dificultad ;si son alguna de las opciones que contemplamos la guarda
ldx #cadena_error ;si no es asi vuelve a pedir la dificultad
jsr imprime_cadena ;la cadena...
bra lee_dificultad ;repetimos el bucle
guarda_dificultad: ;esta funcion almacena la letra elegida en la variable maquina para despues poder hacer un switch en la
; inteligencia_artificial
sta maquina
pulu a
rts
;Tirada de la maquina:
tirada_maquina:
ldy #posicion ;antes de nada cargamos en y el puntero del vector
lda maquina ;cargamos la variable en la que tenemos la dificultad elegida
cmpa #'e ;y en funcion de si es una e o una i se va al nivel estupido o al inteligente
lbeq nivel_estupido
cmpa #'E
lbeq nivel_estupido
nivel_inteligente:; EMPIEZA LA FIESTA
lda tiradas ;en funcion del numero de tiradas hace una cosa u otra, variable que tambien usamos para saber cuando hay empate
cmpa #0
lbeq primeros_movimientos
cmpa #1
lbeq primer_movimiento
cmpa #2
lbeq primeros_movimientos
lda jugador2
sta incognita
lbra inteligencia_artificial
primer_movimiento: ;El primer movimiento seria aquel en el que solo hay una ficha y es del humano
ldb #8 ;asique nosotros intentamos guardar en el centro, y si el humano la ha puesto ahi entoces la ponemos en una
;esquina cualquiera
lda [b,y]
cmpa #'?
lbeq guardar
jsr rand ;generamos un numero aleatorio que nos dira en que esquina guardamos, esto ademas hace,
;mas impredecible la serie aleatoria
ldb semilla
andb #0b00000011 ;esto nos devuelve un numero de 0 a 3
cmpb #0
lbeq esquina1
cmpb #1
lbeq esquina2
cmpb #2
lbeq esquina3
cmpb #3
lbeq esquina4
esquina1: ;Cuatro esquinitas tiene mi cama...
ldb #0
lda [b,y]
cmpa #'?
lbeq guardar
lbra primer_movimiento
esquina2:
ldb #4
lda [b,y]
cmpa #'?
lbeq guardar
lbra primer_movimiento
esquina3:
ldb #12
lda [b,y]
cmpa #'?
lbeq guardar
lbra primer_movimiento
esquina4:
ldb #16
lda [b,y]
cmpa #'?
lbeq guardar
lbra primer_movimiento
primeros_movimientos: ;Bien, esta es la gracia de la I.A.:
;Estudiando el tres en raya hemos llegado a la conclusionde que si el primer movimiento es en el centro,
;el segundo en una casilla en la mitad de una fila o una columna y el tercero en una esquina no contenida
;en la fila o columna del segundo movimiento, el juego
;solo puede terminar en victoria o empate. Esto garantiza que nuestra I.A. nunca perdera. (H)(H)(H)
;Para esto lo que hacemos es que si el segundo movimiento es una ficha en una casilla intermedia,
;nosotros lo colocaremos en una fila o columna opuesta. Si por el contrario el la coloca en una
;esquina, nosotros lo haremos en una intermedia, puesto que asi tendremos dos en raya, y la
; tercera libre, aumentando nuestras posibilidades. Para ahorrar codigo hemos indexado estas jugadas.
;la tirada en el centro esta indexada para poder reutilizar la etiqueta cuando no se han producido tiradas
centro:
ldb #8
lda [b,y]
cmpa #'?
lbeq guardar
primera:
lda [,y]
cmpa jugador1
lbne segunda
ldb #14
lbra guardar
segunda:
lda [2,y]
cmpa jugador1
lbne tercera
ldb #12
lbra guardar
tercera:
lda [4,y]
cmpa jugador1
lbne cuarta
ldb #6
lbra guardar
cuarta:
lda [6,y]
cmpa jugador1
lbne quinta
ldb #16
lbra guardar
quinta:
lda [10,y]
cmpa jugador1
lbne sexta
ldb #0
lbra guardar
sexta:
lda [12,y]
cmpa jugador1
lbne septima
ldb #10
lbra guardar
septima:
lda [14,y]
cmpa jugador1
lbne octava
ldb #4
lbra guardar
octava:
lda [16,y]
cmpa jugador1
lbne inteligencia_artificial
ldb #2
lbra guardar
inteligencia_artificial: ;a partir de aqui el programa busca 2 suyas para poner una tercera, y si no es posibe,
;busca dos del enemigo para no dejarle ganar
clra
sta columna
diagonalI: ;primero buscamos 2 en la primera diagonal
clra
sta columna ;columna es una variable que hemos reutilizado inteligentemente para
;contar cuantos elementos iguales hemos encontrado
lda [0,y]
cmpa incognita
lbne seguir1
jsr sumar
seguir1:
lda [8,y]
cmpa incognita
lbne seguir2
jsr sumar
seguir2:
lda [16,y]
cmpa incognita
lbne seguir3
jsr sumar
seguir3:
lda columna
cmpa #2
lbeq guardar_diagonalI ;si no las encontramos nos vamos a la segunda diagonal
clra
sta columna
diagonalD:
clra
sta columna
lda [4,y]
cmpa incognita
lbne seguir4
jsr sumar
seguir4:
lda [8,y]
cmpa incognita
lbne seguir5
jsr sumar
seguir5:
lda [12,y]
cmpa incognita
lbne seguir6
jsr sumar
seguir6:
lda columna
cmpa #2
lbeq guardar_diagonalD
clra
sta columna
clrb
buscar_enfilas:
clrb
enfilas:
lda [b,y]
cmpa incognita
bne seguir_fila
jsr sumar
seguir_fila:
incb incb
lda [b,y]
cmpa incognita
bne seguir_fila2
jsr sumar
seguir_fila2:
incb incb
lda [b,y]
cmpa incognita
bne siguiente_fila
jsr sumar
siguiente_fila:
lda columna
cmpa #2
beq guardar_fila
clra
sta columna
cmpb #16
bhs buscar_encolumnas
incb incb
bra enfilas
buscar_encolumnas: ;busca en las columnas dos fichas iguales
clrb
encolumnas:
clra
sta columna
lda [b,y]
cmpa incognita
bne seguir_columna
jsr sumar
seguir_columna:
addb #6
lda [b,y]
cmpa incognita
bne seguir_columna2
jsr sumar
seguir_columna2:
addb #6
lda [b,y]
cmpa incognita
bne seguir_columna3
jsr sumar
seguir_columna3:
lda columna
cmpa #2
beq guardar_columna
cmpb #16
beq ir_a_no_perder
subb #10
bra encolumnas
ir_a_no_perder:
lda incognita ; comprueba que ficha ha estado buscando
cmpa jugador1 ;si era la del jugador uno, quiere decir que no puede ganar,
;ni dejar ganar asique hace un movimiento aleatorio
lbeq nivel_estupido
lda jugador1 ;si ha estado buscando su ficha, entonces carga la del jugador uno para no dejarle ganar
sta incognita
lbra inteligencia_artificial
guardar_columna: ;estas funciones intentan guardar solo si la columna tiene posiciones libres
subb #12
guardar_encolumna:
clra
sta indice
nuevo_guardarencolumna:
lda [b,y]
cmpa #'?
lbeq guardar
lda indice
inca
sta indice
cmpa #3
beq salirdeaqui
addb #6
bra nuevo_guardarencolumna
salirdeaqui:
subb #10
lbra encolumnas
guardar_fila:
subb #4 ;se resta 4 para q nos de el valor inicial de la fila
clra
sta indice
nuevo_guardarenfila:
lda indice
inca
sta indice
lda [b,y]
cmpa #'?
beq guardar
lda indice
cmpa #3
lbeq enfilas
incb incb
bra nuevo_guardarenfila
guardar_diagonalD:
ldb #4
lda [b,y]
cmpa #'?
lbeq guardar
ldb #8
lda [b,y]
cmpa #'?
lbeq guardar
ldb #12
lda [b,y]
cmpa #'?
lbeq guardar
lbra buscar_enfilas
guardar_diagonalI:
ldb #0
lda [b,y]
cmpa #'?
lbeq guardar
ldb #8
lda [b,y]
cmpa #'?
lbeq guardar
ldb #16
lda [b,y]
cmpa #'?
lbeq guardar
lbra diagonalD
sumar:
pshu a
lda columna
inca
sta columna
pulu a
rts
nivel_estupido: ;el nivel estupido genera un numero par aleatorio de 0 a 16 e intenta guardar en esa posicion,
;si no intenta guardar en la siguiente y asi sucesivamente dando la
;vuelta al tablero hasta que puede guardar.
jsr rand
ldb semilla+1
andb #0b00001111
incb
andb #0b00011110
intentar_estupido:
cmpb #18
bhs reset_estupido
lda [b,y]
cmpa #'?
beq guardar
addb #2
bra intentar_estupido
reset_estupido:
subb #18
bra intentar_estupido
guardar:
lda jugador2
sta [b,y]
rts