programar usuario maquina en c++

LioNHearT

muy buenas a todos.

estoy realizando un proyecto. trata sobre un juego (jugador vs CPU). la cuestion es que he de programar a la maquina para que juegue como una persona. la idea del juego es la siguiente:

pienso un numero, entonces la maquina pienso un numero al azar (de igual longitud). yo le respondo cuales numeros ha acertado y a partir de ahi continua preguntandome con otro numero, variando los que haya acertado. es decir:

1- pienso nº.
2- maquina me dice un nº aleatorio.
3- le digo cuales ha acertado.
4- maquina procesa dichos numeros y me dice otro nº.

lo hare mejor con un ejemplo:

(pienso un nº7894)

MAQUINA- 1234
YO- 1 acierto.
MAQUINA-1789
YO- 0 aciertos
MAQUINA-7289
YO-0 aciertos
MAQUINA-7839
YO-0 aciertos
MAQUINA-7834
YO-2 aciertos
....

asi hasta x intentos, y si lo acierta antes, gana. la duda que tengo es com podria programar esto, ya que claro, al ser codigo podemos poner que lo encuentre muy facilmente y tal...

que me aconsejais?

gracias.

pd: no pido codigo ni nada, solo la idea de como programar la "inteligencia" de la maquina.

Poisonous

Pues pienso q seria interesante ir almacenando los numeros que dan algun acierto y comparandolos entre si para asi para ir descubriendo cuales son las cifras que dan el acierto.

Soltrac

Tengo q reconocer q soy un manta programando inteligencia artificial, pero bueno. Propongo mi idea (q te puedo asegurar q no es la más rápida, pero acabará adivinándolo).

La idea es q la máquina debe tener memoria de los números q ha ido introduciendo. Los pondrá en varios niveles: Si acierta 0, será el peor nivel, si acierto 3 el mejor (4 es el resultado correcto).

1) Empieza en un nivel 0. En este caso tiene 2 opciones:

2) Acertar 0 o acertar mas de 0

3) Si acierta 0, intenta generar un nº completamente distinto (no pueden coincidir cifras para no perder tiempo).

4) Si acierta mas de 1, intentará generar aleatoriamente un nº con ese nº de cifras acertadas + un nº de cifras del nivel 0.

5) Si sube o se mantiene el nivel, la máquina creerá q está por buen camino, por lo q seguirá intentándolo.

6) Si baja nivel, guarda el nº en su nivel correspondiente y genera un número a partir de 4 con otras cifras, pues en este caso se habrá confundido en la decisión.

Una pregunta que te harás es...que cifras irá tomando? La máquina podría decidirlo a partir de los nº q tiene en cada nivel.

Por ejemplo, si está intentando averiguar el 7698 y está en nivel 1 y tiene guardados el 1659, 4632, 1456, intentará pensar q el 6 es el correcto porque es el q se repite más veces. Por supuesto, cuando está en un nivel superior, tiene q mirar las coincidencias de los niveles de abajo, para ver si va por buen camino o no.

Es decir, si está en nivel 2 buscando el 7698 y tiene guardados el 1623 y el 1290 en el nivel 2 y en el nivel 1 tiene el 4612, 1027, supondrá q los buenos son el 1 y el 6, porque son los q le coinciden con el nivel superior. Por supuesto el nivel 0 servirá como eliminación, porque si tiene en nivel 0 el 4582 y en nivel 1 tiene el 3612, eliminará automáticamente el 2 último, porque sabe que no puede darse nunca el caso.

Como te he dicho, se puede mejorar, pero para empezar podría funcionar.

GaN2

Hummm, lo que puedes hacer es que según el numero de aciertos vaya cambiando un número u otro, por ejemplo:

  • Te dice 1234 y tienes 1 acierto, entonces cambia el 1. Te dice 0234, ahora resulta que tienes 0 aciertos, entonces sabe que el 1 era un acierto, así que lo vuelve a cambiar y varía el 2. Si te sigue diciendo que tienes 1 acierto, entonces sabe que el acierto está entre 234.

  • Hace lo mismo que en el punto 234, dejando fijos los que encuentre.

Es cuestión de que la máquina vaya probando número a número y almacenando los que encuentre.

uplink

Inteligencia artificial = Poco de inteligente y mucho de artificial.

By Sergio Galvez (www.uma.es)

LOc0

Me quedo con el método de #4. Numerito aleatorio de 4 cifras para empezar y empiezas a preguntar al usuario:

[Caso 1] Sacas 0 aciertos ->[/b] Eliminas ese número (concretamente eliminas cada cifra en su respectiva posición).

[Caso 2] Sacas 1, 2 aciertos -> Cambias UNA cifra y preguntas:

2.1) Si bajas un acierto es que la cifra anterior era la BUENA de esa posición. Ya la puedes fijar.

2.2) Si te quedas igual es que la cifra que has cambiado NO va en ese hueco, así que te la puedes cargar.

2.3) Si subes un acierto es que la cifra nueva es la BUENA de ese hueco. YA la puedes fijar.

[Caso 3] Sacas 3 aciertos -> Cambias UNA cifra y preguntas:

3.1) Si bajas un acierto es que la cifra anterior era la BUENA de esa posición. Ya la puedes fijar.

3.2) Si te quedas igual es que la cifra que has cambiado NO va en ese hueco, así que te la puedes cargar. (Además, como tienes 3 aciertos ya, sabes que la que te falta es del hueco en el que estás).

3.3) Si subes un acierto es que la cifra nueva es la BUENA de ese hueco y además... ¡BINGO! Tienes las 4 xD

[Caso 4] Sacas 4 aciertos -> ¡Joder qué potra xD!

Y repetir.

Cuando generes el número de 4 cifras para preguntar al usuario, evita las cifras eliminadas en cada hueco y los huecos que ya tienes fijados. (Puedes usar una matriz booleana de [4][10] para los eliminados y un array de int[4] con las cifras que vayas acertando).

Salu2 ;)

JuAn4k4

Eso no funciona

(Pienso el 1234)

La maquina dice : 1567
1 acierto
Luego cambia el 1: 2567
1 acierto

Si sube el nº de aciertos, la otra era mala y la nueva buena. Si bajas el numero de aciertos, la vieja era buena y la nueva mala. si te quedas igual no haces nada.

(2567)

1234 - 1

1235 - 2

1236 - 2

1237 - 2

-> 567 seguros.

Te queda averiguar uno entre 123.

5671

5672

5673

Win. En 7 pasos.

Otro :
(9826)

1234 - 1

1235 - 1

1236 - 2 ( 5 No , 4 Tampoco , 6 Si)

1237 - 1 ( 7 No )
Solo tenemos el 6, y uno entre 123 . Y no son ni 4,5,6,7 solo quedan 8,9, luego esos seguro que son.

Intentas
3689 - 3

2689 - 4

1689 - 3

Win en 7 pasos.

No se si es para todos los casos, eso si, el 0 si lo metes esto no funciona.

LOc0

Eso no funciona

(Pienso el 1234)

La maquina dice : 1567
1 acierto
Luego cambia el 1: 2567
1 acierto

#7 Creí entender de #1 que para que te de acierto tiene que coincidir cifra y hueco. El 2567 debe dar 0 aciertos, por lo que el 1 era el bueno de la primera posición.

Salu2 ;)

JuAn4k4

Yo jugaba sin huecos. xD Solo acertar numeros x

LioNHearT

la estrategia de #4 era la k tenia pensada. es decir, ir rotando los ke acierte y a partir de ahi calcular. entonces lo ke aria es, en vez d generer un nº cada vez, realizar un bucle de x vueltas cada vez, donde a x mas alta, dificultad mas alta. creo k sera lo mejor.

merci!

Kartalon

Descomponemos el número obtenido por el input.

Cuatro TAD's lista con diez posiciones cada lista. Cada lista corresponde para una cifra.

Cuatro flags iniciados a FALSE.

Mientras no se acierten todos los números (no son todos los flags TRUE)...
Inicio bucle.

Para cada flag FALSE...
Inicio bucle.
Obtienes una posición aleatoria de la lista correspondiente (eliminando el valor de la lista) y lo almacenamos en un int.
Fin del bucle.

Mostramos el número en pantalla, comparamos valores y seteamos a TRUE los flags acertados.

Fin del bucle.

Si no me equivoco, más o menos es algo así lo que buscas.

Soltrac

#11 Eso no es inteligencia artificial, eso es fuerza bruta. Probando del 0000 hasta el 9999 xDDDD. Además el programa no te dice q posiciones has acertado, solo cuantas has acertado.

Por cierto #1, este tema es interesante, a ver si es posible cuando termines q nos cuelgues el código final. Siempre me ha apasionado la inteligencia artificial.

0buS

yo tengo hecho un mastermind con numeros, osease eso mismo xD.

PD. por supuesto que nada de inteligencia artificial y esas cosas, que es programacion de 1º xD.

cracking

ese juego es imposible q lo programes en plan 100%seguro, ya que si tu y yo jugamos a ese juego, piensa... como jugarias? es casi imposible adivinarlo, seria casi azar, tendrias q decir como en el mastermind ese, el numero de aciertos y la posicion del acierto, osea, si pienso el 1234 y me dice el 1243 deberia decir q hay 4 aciertos, 2 en su posicion y otros 2 q no tan en su posicion, entonces alomejor lo logras matematicamente. creo vamos.. esq sino es muy aleatorio

PD: me baso en la realidad, pa programar algo tienes q pensar como solucionarias tú el problema, y yo por lo menos no seria capaz de adivinar el numero usando ningun metodo XD, seria probando probando y probando... XD porq con el 1234 aun es "facil"... pero cuando sean numeros mas largos, en plan 1237838... millones de combinaciones posibles si le dices solo el numero de aciertos XD

Poisonous

#14 Cuando se trabaja con intelegencia artificial las probabilidades juegan un papel muy importante, aparte de que no siempre se puede encontrar solucion optima.
De todos modos, dando el suficiente numero de pistas este problema es determinnista. Si el numero es 103123213 millones pues necesitaras muchisimas pistas, pero se acabrá encontrando solucion

cracking

aaaaahm

LOc0

#14

Imposible ya te digo que NO es porque lo tengo delante codificado usando el método descrito en #6 y te "adivina" uno de 5 cifras con unas 15 preguntas de media.

(Me dio por codificarlo porque es un tema que me interesa ya que a lo mejor oriento el PFC por alguna rama de IA...)

De todas formas, lo que he implementado apenas tiene IA ya que el problema no se presta demasiado (se pueden ir asignando probabilidades a cada candidato para tener una pequeña heurística a la hora de generar los números para tardar menos, pero te obliga a realizar preguntas de "calentamiento" que al final te aumentan el total de pistas ¬¬...)

Salu2 ;)

#19 -> "Mapunto" ( en veranito of course ;) )

Kartalon

#12 Sí, es fuerza bruta, pero vamos, que #1 no pide inteligencia artificial hasta donde yo leo y al ser números relativamente bajos (cuatro cifras) nunca tardaría mucho en adivinarlo (unas 20 preguntas y al escogerse cifras forma aleatoria la experiencia del usuario tenderá a ser positiva).

Y básicamente es una implementación particular con listas de lo descrito en #6

C

Tanto que otras veces se proponen programas para desarrollar cada uno y comparar cuál es el mejor algoritmo, y #1 ha planteado un caso buenísimo (y accesible de desarrollar para cualquiera con 2 dedos de frente y que conozca lo mínimo de programación). Si fuera el típico mastermind que te indica si la posición es la buena, el programa tiene poco margen de maniobra, pero el hecho de no saber si la posición es buena veo que da juego para aburrir. (Creo que eso es lo que ha planteado #1, no?)

Y es fácil medir la eficiencia de cada algoritmo. Le sometemos a 10.000 número aleatorios y hallamos la media del número de propuestas que ha tenido que realizar para cada número.

Soy el típico analista programador, casado, con mil ocupaciones, pero me apetece (y me sorprende a estas alturas de me vida...).

¿Alguien se apunta?

No hay prisa... yo lo mismo reabro el hilo dentro de 2 meses cuando tenga vacas y me baje a la piscina con el notebook y así me entretengo (mis vecinas son unos troles).

P.D.: Parece fácil y todos iremos por caminos muy similares. Pero la experiencia me dice (me dedico al marketing relacional y técnicas olap) que ciertos matices pequeños en el algoritmo puede producir resultados asombrosos. Y no hace falta recurrir a la IA de libro, sino a la IN que tenemos cada uno en el coco.
Digo esto último porque muchos se dejan llevar por la implementación del típico algoritmo recursivo con una pobre gestión de la "memoria" o inputs previos que son los que acotan las posibilidades. Y si bien hay técnicas para esto, a la hora de tirar código, la pericia de cada uno es clave a la hora de gestionar esa "memoria" que puede tener el algoritmo.

El caso que indica #6 (pavo al que respeto pq se le ve con buen coco xD) es el típico a priori que todos hemos pensado. Pero (y no es por ir de listo x la vida) le veo muy básico. En 0,0001 milisegundos me vienen unas cuantas formas de abordar el algoritmo de una forma más eficiente.

LOc0
spoiler

Yo mismo.

spoiler

Suena a coña, pero siempre que sale algún thread de "estos" tengo 6782638273 exámenes a 6 días vista. Y algunos ya tenéis carrera, trabajo y familia, pero otros no ;)...

spoiler

Primero gracias por lo del coco :P Y volviendo al tema, pues tienes toda la razón. Es un método muy básico. De hecho no colgué el código por eso mismo. En los ratillos que tengo libres he estado pensando en "truquis" para no preguntar al usuario por cada candidato de forma tan aleatoria, pero todos los que se me ocurren requieren al final realizar tantas o más preguntas que el método "a piñón fijo"...

Lo dicho, por mi parte en cuanto pase la tormenta me apunto y me gustaría que los gurús del foro (que los hay) lo hicieran tb. A lo mejor hasta aprendemos algo y todo.

Salu2 ;)

Soltrac

Se me ha ocurrido muy por encima una forma de acotar el algoritmo para hacer algo más eficiente la búsqueda de #6, pero tengo un problema muy gordo:

No me gusta programar. Soy informático, pero solo por trabajo, no por afición. No se si sería capaz de ponerme a pensar unas horas de mi tiempo libre en hacer lo q hago cada día 8 horas diarias. Tendré vacaciones en Julio, si lo dejamos para esa fecha, prometo ponerme alguna mañana a participar a este juego.

Y entiendo, q para poder comparar algoritmos, deberíamos poner más cifras. Con 4 cifras, las iteraciones van a ser muy parecidas, pero con mas empezarán a ser diferentes.

Usuarios habituales

  • Soltrac
  • LOc0
  • Kartalon
  • cracking
  • Poisonous
  • LioNHearT
  • JuAn4k4