2009-05-08 22 views
14

Mi hijo tenía una tarea para escribir Blackjack en Java. Lo ayudé un poco, pero en su mayor parte él mismo lo hizo y en realidad juega bastante bien. Incluso captó un error que no vi en cómo estaba calculando los valores de la mano. Sin embargo, hay un inconveniente con el que no ha tratado y cada solución que puedo pensar es realmente complicada y mucho más allá de lo que va a poder codificar fácilmente con sus habilidades Java aún rudimentarias.¿Hay alguna manera elegante de lidiar con el As en Blackjack?

The Ace. De hecho, no es solo un As, hay cuatro de ellos y posiblemente puedas obtener los cuatro en una sola mano. ¿Cómo lidiar elegantemente con el cálculo del valor de una mano de cartas cuando hay uno o más Ases, cada uno de los cuales puede estar valorado en uno u once? Siento que debería haber un algoritmo elegante para eso, pero no lo estoy viendo. Por supuesto, parte de eso podría ser simplemente que estoy cansado, pero quizás puedas ayudar.

Respuesta

24

Sólo tratan cada as como 11. A continuación, mientras que el valor es mayor de 21 años, restar 10 del su total por cada as en su mano.

+1

Agradable y elegante, además de tener que mirar más de una vez a las cartas. +1 –

+3

No tiene que mirar necesariamente más de una vez. Solo mantén un recuento de ases la primera vez que mires. –

+9

Es sorprendente cómo la respuesta incorrecta se vota hasta la cima. Como se han notado las siguientes respuestas correctas, solo un as se cuenta como 11, por lo que es mucho más eficiente contar cada as como 1, luego, si encuentras un as, y el total <12, suma 10. No es necesario realizar un seguimiento de cuántos Ases, y solo se necesita un complemento adicional. Si agregó 10, puede establecer un indicador "suave" si necesita rastrear si un total es difícil o blando. –

-1

El problema es que no está determinado: puede contar (según entiendo las reglas) un As como 1 u 11. Pero usted sabe que no va a contarlo como 11 cada vez, porque lo hará busto.

La única solución que creo que es para calcular la puntuación para cada valor posible de la ACE, donde la suma < = 21.

3

No importa que todos los as se contabilicen como valor total como 11, cuando la suma total ha alcanzado más de 21 resta 10 de la mano, pero el hecho es que debes asegurarte de contar cuántas veces restas 10 y cuántas veces se agrega 11 (un as),

añadir 11> = restar 10 - debe ser siempre satisfecho

ejemplo alorithm:

int sum=0; 
int ace=0; 
int subtract=0; 
while(!busted or !stay) 
{ 
    Hitme(value); 
    if(value=11)ace++; 
    sum+=value; 
    if(sum>21) 
    { 
     if(ace>=1) 
     { 
     if(ace>=subtract) 
     { 
      sum-=10 
      subtract++; 
     } 
     else 
     { 
      busted; 
     } 
     } 
     else 
     { 
      busted; 
     } 
    } 
    else 
    { 
    hit or stay; 
    //of course if sum== 21 then force stay 

    } 
} 
7

Solo usarás 1 ace para los 11 puntos. Así calcular todos excepto el último as como 1 y si tienen 10 o menos puntos, el último as cuenta como 10.

+1

Imagine un jugador que comienza con ace-2. Golpean get y ace, golpean nuevamente get y ace, golpean nuevamente get y ace. ¡Incluso con una sola baraja tienen cuatro! Con un zapato multideck, puede ser peor. Mantenga un conteo y un descuento según sea necesario ... – dmckee

4

Sólo 1 Ace siempre vale por 11.

Por lo tanto, un método alternativo para el tratamiento de cada As como 11 sería tratar a cada As como 1. Luego agregue 10 al valor total (transportado independientemente de Ace en mano) y consérvelo en una variable "alta" separada (valor + 10). También crea un booleano de ~ ace: true si (cualquier) as aparece.

Y así cuando se compara el puntaje con el distribuidor; comprueba si la mano de los jugadores tiene (cualquier) As, en cuyo caso puedes (usar) el valor "alto", de lo contrario (sin As) usar el valor "bajo".

De esta forma King + 9 + Ace (mal ejemplo quizás) sería ~ bajo: 20 & alto: 30 & as: cierto - Con esa información puede verificar si 30 - 10 "ganará el juego". Entonces, King + 5 + 5 (bajo: 20 alto: 30 ace: falso) no usará su valor alto de 30.

Estoy usando este método, así que sé cuándo mostrar una alt. As score en pantalla; como 3/13 (Ace + 2), usando el mismo as: verdadero | falso booleano que ya tengo. Esta es seguramente la misma respuesta que la primera, pero esto tiene más sentido para mí :)

2

Similar a la respuesta de elundmark ...

Probablemente haya obtenido un método que evalúa el valor de una mano de blackjack. Siempre valora los ases en un punto. Si una mano contiene un as, calcule un valor difícil (todos los ases son unos, +10) y un valor suave (todos los ases).

Si el valor fijo no es una falla, devuelva el valor difícil. Si el valor fijo es una falla, devuelva el valor suave.

ejemplo 1
2, A, A
valor duro 2 + 1 + 1 + 10 = 14
valor suave = 2 + 1 + 1 = 4

valor duro < 21, por lo retorno de disco duro valor (valor de la mano es 14)

ejemplo 2
2, A, A, 8
valor duro = 2 + 1 + 1 + 8 + 10 = 22 (busto)
valor suave = 2 + 1 + 1 + 8 = 12

valor dura> 21, por lo que devolver el valor blando (valor de la mano es 12)

El pensamiento tradicional acerca de las reglas y la forma en que el juego se juega, es que el valor de un As es condicional y puede tener dos valores, 1 o 11. Este concepto es difícil de implementar. Es mucho más fácil para un programador contar todos los Ases como un valor de uno y condicionalmente agregar 10 puntos al valor de la mano. De esa manera, la implementación de su Rango o Valor de la Tarjeta puede permanecer rígida y directa. He experimentado con esto antes al devolver una colección de valores y un par de otros métodos. Es un dolor, y no vale la pena solo por el rango de As.

Si desea mostrar un alt en la pantalla como 2/12, en lugar de devolver un entero, simplemente devuelva un objeto "BlackjackValue" que contiene un Entero y un objeto String que cree en el método que evalúa su mano valor.

0
short aces_count = 0; 
short non_aces_sum = 0; 
short global_sum = 0; 

foreach card in _card:{ 
    if(card.value != 11){ // assuming ace value is 11 
     if(card.value > 10) 
      non_aces_sum += 10; 
     else 
      non_aces_sum += card.value 
    }else 
     aces_count += 1; 
} 

short aces_sum = 0; 
if(aces_count > 0) aces_sum = 11; 

for(int i=0 ; i < aces_count - 1; i++){ // - 1 cuz already asigned first ace 
    aces_sum += 1; // 2x aces == 22 so max 1 ace has value 11 
} 
if(aces_sum + non_aces_sum > 21) 
    aces_sum = aces_count; // no need for an 11 value ace, so all are 1 

global_sum = non_aces_sum + aces_sum; 
Cuestiones relacionadas