Apagada docs

Aprendiendo a programar el pasado

Herramientas de usuario

Herramientas del sitio


en:basic:take_3

Take 3 for Chipmunk Basic

Take or “the ancient game of Nim” is a game where each player removes from one to all sticks in a row inside a pyramid of sticks.

Depending on versions, player who takes last stick or doesn't wins.

This should run on chipmunk basic for the Macintosh, and should probably run on any console-oriented basic also (ubasic, gwbasic, and so on).

10 dim a(3) : dim posi$(50) : puntero = 0 : dim gana(50)
20 for f = 0 to ubound(a) : a(f) = 0 : next
25 print "Calculando posiciones, espere..."
30 goto 110
40 n = ubound(a)
50 a(n) = a(n)+1
60 if a(n) <= (n+1) then 110
70 n = n-1
80 if n < 0 then 180
90 for g = n+1 to ubound(a) : a(g) = a(n)+1 : next g
100 goto 50
110 for f = 0 to ubound(a)
120 posi$(puntero) = posi$(puntero)+chr$(48+a(f))
130 rem print a(f);
140 next f
150 print posi$(puntero);" ";
160 puntero = puntero+1
170 goto 40
180 puntero = puntero-1
190 print
200 gosub 4000 : print
210 posac$ = posi$(puntero)
220 gosub 5000
225 gosub 8000
230 input "¿Comienza el Humano o el Computador (H/C)? ";r$
240 if r$ = "H" or r$ = "h" then turno = 1 : goto 280
250 if r$ = "C" or r$ = "c" then turno = 0 : goto 280
260 print "Responda H o C"
270 goto 230
280 if turno = 1 then gosub 6000 :  else gosub 7000
290 if posac$ = "0000" then goto 320
300 turno = (turno+1) mod 2 : goto 280
320 print "El ";
330 if turno = 0 then print " computador "; :  else print " humano ";
340 print "ha perdido."
350 input "¿Otra partida (S/N)? ";r$
360 if r$ = "S" or r$ = "s" then goto 210
370 if r$ = "N" or r$ = "n" then end
380 print "Responda 'S' o 'N'."
390 goto 350
2000 rem BUSCAR POSICION
2010 max = puntero : min = 0
2020 n = min+int((max-min)/2)
2030 if posi$(n) = buscame$ then buscap = n : return
2040 if posi$(n) > buscame$ then max = n-1
2050 if posi$(n) < buscame$ then min = n+1
2060 if max >= min then 2020
2070 buscap = -1 : return
3000 rem ORDENAR CADENA
3010 for ford = len(ord$) to 2 step -1
3020 for gord = 1 to ford-1
3030 if mid$(ord$,gord,1) > mid$(ord$,gord+1,1) then m$ = mid$(ord$,gord+1,1)+mid$(ord$,gord,1) : mid$(ord$,gord,2) = m$
3040 next gord
3050 next ford
3060 return
4000 rem buscar jugadas perdedoras
4010 rem "0" es una jugada ganadora: quien llega a ella, gana.
4020 rem "1" es una jugada perdedora: quien llega a ella, pierde.
4030 rem Todas las jugadas que no permitan llevar al adversario  a posición
4040 rem perdedora son posiciones perdedoras.
4050 for f = 0 to puntero : gana(f) = -99 : next
4060 buscame$ = "0000" : gosub 2000 : gana(buscap) = 0
4070 buscame$ = "0001" : gosub 2000 : gana(buscap) = -1
4080 marcados = 0
4090 pact = buscap+1
4100 rem Quitar palitos a cada columna para saber a qué posiciones
4110 rem lleva la posición actual.
4120 rem si la posición actual lleva a alguna posición marcada como
4130 rem gana(xxx)=-99, volver a marcar la posición actual como gana(pact)=-99
4140 rem si la posición actual lleva a alguna posición marcada como perdedora
4150 rem (gana(xxx)=-yyy, mayor que -99), marcarla como ganadora (gana(pact)=xxx
4160 rem en cualquier otro caso, marcar la posición como perdedora (-1)
4170 print "Calculando tabla de movimientos. Espere..."
4180 gana(pact) = -1 : c$ = posi$(pact) : fp = len(c$)
4190 rem print
4200 print posi$(pact);" ";' "=> ";
4210 c$ = posi$(pact) : if mid$(c$,fp,1) = "0" then 4310
4220 mid$(c$,fp,1) = chr$(asc(mid$(c$,fp,1))-1)
4230 ord$ = c$ : gosub 3000
4240 buscame$ = ord$ : gosub 2000
4250 rem print posi$(buscap);", ";
4260 if gana(buscap) = -99 then gana(pact) = -99 : goto 4310
4270 if gana(buscap) < 0 then gana(pact) = buscap : goto 4310 : rem print "[";posi$(buscap);"] ";
4280 rem if gana(buscap) >= 0 then print posi$(buscap);" ";
4290 if mid$(c$,fp,1) > "0" then 4220
4300 fp = fp-1 : if fp > 0 then goto 4210
4310 rem acabando con la posición pact
4320 pact = pact+1
4330 if pact > puntero then goto 4350
4340 goto 4180
4350 rem busca piezas no definidas para repetir el proceso...
4360 pact = 1
4370 if gana(pact) = -99 then print posi$(pact);" no definida."
4380 pact = pact+1
4390 if pact <= puntero then 4370
4400 return
4410 print "Posiciones perdedoras"
4420 for f = 1 to puntero
4430 if gana(f) > 0 then print posi$(f);" ";
4440 next
4450 print "Posiciones perdedoras"
4460 for f = 1 to puntero
4470 if gana(f) < 0 then print posi$(f);" ";
4480 next : print
4490 end
5000 rem dibujar los palitos
5010 print
5020 for fdib = 1 to len(posac$)
5030 print chr$(asc("A")+fdib-1);" ";
5040 for gdib = 1 to asc(mid$(posac$,fdib,1))-48
5050 print "| ";
5060 next gdib
5070 print
5080 next fdib
5090 return
6000 rem Mueve el humano
6005 gosub 5000
6010 input "¿De qué fila va a coger la pieza (escriba la letra de la fila)? ";r$
6020 r = asc(r$)-asc("A")+1
6030 if r < 1 or r > len(posac$) then print "Filas desde la A hasta la ";chr$(len(posac$)+asc("A")-1);"." : goto 6010
6040 if mid$(posac$,r,1) <= "0" then print "Fila vacía; elija otra." : goto 6010
6050 input "¿Cuántos palitos desea coger (mínimo 1; escriba 0 para cambiar de fila)? ";palitos
6060 if palitos = 0 then print "Bien, escoja otra fila, si así lo desea." : goto 6010
6070 if palitos < 0 then print "Mínimo 1 palito. Para cambiar de fila, escriba 0." : goto 6050
6080 if palitos+asc("0") > asc(mid$(posac$,r,1)) then print "En esa fila sólo hay ";asc(mid$(posac$,r,1))-asc("0");" palitos." : goto 6050
6090 n$ = chr$(asc(mid$(posac$,r,1))-palitos)
6100 mid$(posac$,r,1) = n$
6110 return
7000 rem Mueve el computador
7010 gosub 5000
7020 ord$ = posac$ : gosub 3000
7030 pcanon$ = ord$
7040 buscame$ = ord$ : gosub 2000
7050 if buscap = -1 then print "Error interno. El ordenador se rinde." : end
7060 if gana(buscap) >= 0 then 7150
7070 rem no conocemos posición ganadora
7080 print "Me lo pones dificil..." : rem print "debug: elegido al azar."
7090 rem elijamos una al azar.
7100 if posac$ = posi$(0) then print "Pero si no quedan palitos!!" : return
7110 r = int(rnd(len(posac$)))+1
7120 if mid$(posac$,r,1) = "0" then 7110
7130 mid$(posac$,r,1) = chr$(asc(mid$(posac$,r,1))-1)
7140 return
7150 rem Conocemos la posición ganadora
7160 rem su valor está en posi$(gana(buscap))
7170 ganac$ = posi$(gana(buscap))
7180 rem Vamos a ver qué cambia entre pcanon (que está ordenada) y
7190 rem ganac$ (que también está ordenada).
7200 rem la diferencia puede consistir en:
7210 rem Hay un cero más en ganac$ => Buscar qué columna falta.
7220 rem Hey el mismo número de ceros => Buscar qué columna baja.
7230 rem print "debugging: comparar ";pcanon$;" con ";ganac$;"."
7240 dim valores(2,10)
7250 for f = 0 to ubound(valores,2) : for g = 0 to 2 : valores(g,f) = 0 : next g : next f
7260 for f = 1 to len(pcanon$)
7270 cifra1 = asc(mid$(pcanon$,f,1))-asc("0")
7280 cifra2 = asc(mid$(ganac$,f,1))-asc("0")
7290 valores(1,cifra1) = valores(1,cifra1)+1
7300 valores(2,cifra2) = valores(2,cifra2)+1
7310 next f
7320 dim vdif(2) : diferencias = 0 : vdif(0) = -1 : vdif(1) = -1
7330 for f = 0 to ubound(valores,2)
7340 if valores(1,f) <> valores(2,f) then vdif(diferencias) = f : diferencias = diferencias+1
7350 next f
7360 if diferencias <> 2 then print "Error." : stop
7370 if diferencias = 0 then print "Error." : stop
7380 m$ = chr$(asc("0")+vdif(0))
7390 n$ = chr$(asc("0")+vdif(1)) : if m$ < n$ then x$ = m$ : m$ = n$ : n$ = x$
7400 rem print "Debug: Donde había ";m$;" hay ";n$;"."
7410 f = 1
7420 if mid$(posac$,f,1) = m$ then mid$(posac$,f,1) = n$ : goto 7440
7430 f = f+1 : if f <= len(posac$) then 7420
7440 return
8000 rem REGLAS
8010 input "¿Desea ver las reglas del juego (S/N)?";r$
8020 if r$ = "S" or r$ = "s" then 8050
8030 if r$ = "N" or r$ = "n" then return
8040 print "Escriba 'S' o 'N'." : goto 8010
8050 print : print "T A K E (también llamado DERNIER o GAME OF NIM)."
8060 print : print "Reglas del juego:"
8070 print "Por turnos, los jugadores toman un palito o más de una sola línea."
8080 print "Pierde el jugador que toma el último palito."
8090 print : print "Estrategia:"
8100 print "Trate de forzar al oponente a llegar a una posición desde la que no"
8110 print "pueda forzarle a vd. a tomar el último palito."
8120 print "En este juego hay MOVIMIENTOS GANADORES y MOVIMIENTOS PERDEDORES."
8130 print "Si juega adecuadamente, el primer jugador siempre gana."
8140 print : return
Este sitio web utiliza cookies. Al utilizar el sitio web, usted acepta almacenar cookies en su computadora. También reconoce que ha leído y entendido nuestra Política de privacidad. Si no está de acuerdo abandone el sitio web.Más información
en/basic/take_3.txt · Última modificación: 2018/01/07 12:01 por nepenthes